@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
|
@@ -52,17 +52,18 @@ describe("Real pilots lint clean under COMP* (#562 acceptance criteria)", () =>
|
|
|
52
52
|
expect(runAll(ctx)).toEqual([]);
|
|
53
53
|
});
|
|
54
54
|
|
|
55
|
-
it("the Neo4j fan-out pilot produces zero COMP* diagnostics other than the expected COMP004 (gate
|
|
55
|
+
it("the Neo4j fan-out pilot produces zero COMP* diagnostics other than the expected COMP004 (a gate ends the run pending approval)", () => {
|
|
56
56
|
// The Neo4j pilot's Node-1 approval gate is a deliberate design choice
|
|
57
|
-
// (see neo4j-fanout.pilot.ts's own docstring and
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
//
|
|
61
|
-
//
|
|
62
|
-
//
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
//
|
|
57
|
+
// (see neo4j-fanout.pilot.ts's own docstring, and ../driver.ts on
|
|
58
|
+
// gate-as-fact, #2119) — a run reaching it stops there pending `chant
|
|
59
|
+
// approve`, which is exactly the standing human wait COMP004 exists to
|
|
60
|
+
// surface, so COMP004 firing here is the *correct*, expected signal, not
|
|
61
|
+
// a defect. A real project would acknowledge it with a file-level
|
|
62
|
+
// `// chant-disable COMP004 -- <reason>` once authored as an actual
|
|
63
|
+
// `*.component.ts` file — a COMP* diagnostic is reported for the whole
|
|
64
|
+
// component and carries no line, so `-line`/`-next-line` do not suppress
|
|
65
|
+
// one (see ../../lint/rules/comp/comp004-gate-needs-durable-runtime.ts
|
|
66
|
+
// and the comp004/pass fixture demonstrating that opt-out end to end).
|
|
66
67
|
const ctx = contextFor([neo4jCluster]);
|
|
67
68
|
const diagnostics = runAll(ctx);
|
|
68
69
|
expect(diagnostics.every((d) => d.checkId === "COMP004")).toBe(true);
|
|
@@ -10,17 +10,17 @@
|
|
|
10
10
|
* single-component path, ./cli-support.ts's `runComponents`), that never
|
|
11
11
|
* changes run ordering, gating, `onFailure`, rollback, or exit codes — it
|
|
12
12
|
* only reports what already happened, as it happens. See ./driver.ts's
|
|
13
|
-
* module doc for what actually executes; streaming progress
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* module doc for what actually executes; streaming progress from a hosted
|
|
14
|
+
* runtime is a separate, later concern (`chant run status`/`log` already ask
|
|
15
|
+
* one for the run state it keeps).
|
|
16
16
|
*
|
|
17
17
|
* `RunProgressEvent` is a discriminated union on `type`, one JSON object per
|
|
18
18
|
* NDJSON line (see `ndjsonProgressSink` below and
|
|
19
19
|
* ../cli/handlers/run.ts's `--progress-json` wiring).
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
/** Terminal status for a wave/component/phase/run — mirrors
|
|
23
|
-
export type RunProgressStatus = "ok" | "failed";
|
|
22
|
+
/** Terminal status for a wave/component/phase/run — mirrors `DriverRunResult.status`'s three outcomes (#2119): `gated` is neither, and reporting it as `failed` would have a progress consumer page someone for a decision nobody has made yet. */
|
|
23
|
+
export type RunProgressStatus = "ok" | "failed" | "gated";
|
|
24
24
|
|
|
25
25
|
/** The run is about to start. `waves` are the parallel-safe waves the run will attempt, in order (see resolveComponentGraph) — 1-based wave numbers in every other event index into this array. */
|
|
26
26
|
export interface RunStartEvent {
|
|
@@ -108,7 +108,7 @@ export type RunProgressSink = (event: RunProgressEvent) => void;
|
|
|
108
108
|
* Build a sink that writes `JSON.stringify(event) + "\n"` to `write` (default:
|
|
109
109
|
* `process.stdout.write`), one line per event, as they happen — the
|
|
110
110
|
* `--progress-json` CLI wiring's sink (../cli/handlers/run.ts, for both the
|
|
111
|
-
* `--components` driver's `RunProgressEvent`s and the
|
|
111
|
+
* `--components` driver's `RunProgressEvent`s and the Op path's
|
|
112
112
|
* `StepRecord`s, chant #1676). Kept separate from `driver-output.ts`'s
|
|
113
113
|
* end-of-run renderers: this emits *during* the run, one line at a time;
|
|
114
114
|
* `renderDriverJson`/`renderDriverHuman` render the completed
|
|
@@ -287,6 +287,25 @@ describe("run() — failed turn: non-zero exit surfaces as status \"failed\", ne
|
|
|
287
287
|
});
|
|
288
288
|
});
|
|
289
289
|
|
|
290
|
+
describe("RunAgentTurn[\"status\"] is exactly the two states run() produces (#2072)", () => {
|
|
291
|
+
it("has no third member: a switch handling only \"completed\" and \"failed\" compiles with no default needed", () => {
|
|
292
|
+
// Compile-time exhaustiveness check, not a runtime assertion: if a third
|
|
293
|
+
// member were ever added back to the union (e.g. "interrupted"), this
|
|
294
|
+
// switch would stop being exhaustive and `tsc` would reject the missing
|
|
295
|
+
// case, since `identity`'s return type has no branch left to satisfy it.
|
|
296
|
+
const identity = (status: RunAgentOutput["turn"]["status"]): "completed" | "failed" => {
|
|
297
|
+
switch (status) {
|
|
298
|
+
case "completed":
|
|
299
|
+
return "completed";
|
|
300
|
+
case "failed":
|
|
301
|
+
return "failed";
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
expect(identity("completed")).toBe("completed");
|
|
305
|
+
expect(identity("failed")).toBe("failed");
|
|
306
|
+
});
|
|
307
|
+
});
|
|
308
|
+
|
|
290
309
|
describe("collectArtifacts — only a \"not found\" read means \"no artifact\"; a genuine infra failure propagates (#1942 review finding 2)", () => {
|
|
291
310
|
it("branch A: readFile rejecting with the sprite-fs \"not found\" shape resolves to empty artifacts.files, not a run() rejection", async () => {
|
|
292
311
|
const { sprites } = makeFakeSprites(succeed); // never writes /work/output — readFile hits the fake's "not found" branch
|
|
@@ -86,9 +86,8 @@
|
|
|
86
86
|
* `run(ctx, input)` was called with, plus (since #1944) the exact `output`
|
|
87
87
|
* `run()` returned — `../capability.ts`'s `Capability.rollback` grew an
|
|
88
88
|
* optional third parameter for precisely this, and ../driver.ts's saga
|
|
89
|
-
* unwind (
|
|
90
|
-
*
|
|
91
|
-
* durable Temporal path) always threads it through. `run()` records the
|
|
89
|
+
* unwind (and any hosting runtime that splits `run`/`rollback` across
|
|
90
|
+
* process boundaries) always threads it through. `run()` records the
|
|
92
91
|
* sprite id and exact pre-run checkpoint id two ways: in a private
|
|
93
92
|
* `WeakMap` keyed by the exact `input` object (works only when `rollback`
|
|
94
93
|
* is called with that same object — true in-process, e.g. this module's
|
|
@@ -115,18 +114,13 @@
|
|
|
115
114
|
* commented no-op return — the same pattern
|
|
116
115
|
* `../../lexicons/aws/src/components/host-delivery.ts`'s `code-deploy`
|
|
117
116
|
* rollback uses (`if (!deploymentId) return;`) — rather than throwing.
|
|
118
|
-
* **Before #1944**,
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
* workflow's saga-unwind loop (`lexicons/temporal/src/component-op/
|
|
126
|
-
* serializer.ts`) also no longer swallows a rollback failure silently
|
|
127
|
-
* (any capability's, not just this one) — it now logs it and surfaces it
|
|
128
|
-
* via a `RollbackFailed` search attribute, defense in depth for a rollback
|
|
129
|
-
* failure unrelated to identity (e.g. the sprite backend itself erroring).
|
|
117
|
+
* **Before #1944**, a hosted path running `run` and `rollback` as separate
|
|
118
|
+
* units of work — each rebuilding `input` fresh via `resolveStepInput` —
|
|
119
|
+
* never gave the `WeakMap` a hit, so a fresh sprite's rollback there
|
|
120
|
+
* silently degraded to that no-op; passing `output` through (this revision)
|
|
121
|
+
* closes that gap directly, without redesigning the component-op wire
|
|
122
|
+
* format — see #1944's PR description for why this was chosen over the
|
|
123
|
+
* "make the degrade loud" alternative.
|
|
130
124
|
* - **Destroy vs. leave-alive.** `run()` destroys a freshly created (not
|
|
131
125
|
* `workspace.spriteName`-reused) sprite only when `turn.status ===
|
|
132
126
|
* "completed"`. An ordinary failed turn leaves the sprite alive — it
|
|
@@ -155,12 +149,6 @@
|
|
|
155
149
|
* snapshot folded into a `BuildArchiveManifest` entry (./build-archive.ts)
|
|
156
150
|
* remains an open question, as does `artifacts.diff`, which `run()` never
|
|
157
151
|
* populates (the real Sprites API has no built-in diff endpoint).
|
|
158
|
-
* - Interrupted turns — `turn.status: "interrupted"` stays in the type but
|
|
159
|
-
* is unreachable from this implementation: any `sprites.exec` rejection
|
|
160
|
-
* (including one caused by an aborted signal) propagates as a genuine
|
|
161
|
-
* `run()` failure rather than being classified as an interrupted turn.
|
|
162
|
-
* Distinguishing "deadline hit mid-run" from "the sprite backend errored"
|
|
163
|
-
* well enough to surface `"interrupted"` safely is left for #1944.
|
|
164
152
|
*
|
|
165
153
|
* **#1943 (this revision) resolved the transcript-hash basis and
|
|
166
154
|
* sign/verify-gate interop, closing #1941's open "transcript hash basis"
|
|
@@ -291,7 +279,7 @@ export interface RunAgentInput {
|
|
|
291
279
|
|
|
292
280
|
/** Mirrors fountain's `Turn` shape (`status`/`exit_code`/`started_at`/`ended_at`), even though the turn itself runs on a chant-owned sprite rather than a fountain-managed `Sandbox`. */
|
|
293
281
|
export interface RunAgentTurn {
|
|
294
|
-
status: "completed" | "failed"
|
|
282
|
+
status: "completed" | "failed";
|
|
295
283
|
exitCode: number | null;
|
|
296
284
|
startedAt: string;
|
|
297
285
|
endedAt: string | null;
|
|
@@ -526,8 +514,8 @@ export function createRunAgentCapability(
|
|
|
526
514
|
async rollback(_ctx, input, output): Promise<void> {
|
|
527
515
|
// The durable-safe channel first (#1944): `output` is the exact value
|
|
528
516
|
// this step's own `run()` returned, threaded through by every current
|
|
529
|
-
// caller (../driver.ts locally,
|
|
530
|
-
//
|
|
517
|
+
// caller (../driver.ts locally, and a hosting runtime across whatever
|
|
518
|
+
// process boundary it puts between the two) — it
|
|
531
519
|
// survives even when `rollback()` is called with a freshly-rebuilt
|
|
532
520
|
// `input` object the in-process WeakMap below has never seen. Falls
|
|
533
521
|
// back to the WeakMap for a caller that predates/never threads
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* configured identity policy and **throws** on any failure, so composing it
|
|
7
7
|
* before an apply phase fails the deploy the same way a thrown capability
|
|
8
8
|
* error already halts `driver.ts`'s step execution — no new failure
|
|
9
|
-
* mechanism, no
|
|
10
|
-
*
|
|
9
|
+
* mechanism, no human-approval semantics (that is `Gate`, ../component.ts, a
|
|
10
|
+
* different concept: a fact on the gate ledger). `verify` is a
|
|
11
11
|
* synchronous, local-executor-safe capability, exactly like `health-gate`
|
|
12
12
|
* (./wait-verify.ts).
|
|
13
13
|
*
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
normalizeDeepProperties,
|
|
13
13
|
type DeepNormalizationHooks,
|
|
14
14
|
} from "./deep-observation";
|
|
15
|
+
import { HELD_ELSEWHERE_TAG, heldElsewhere, isNormalizedHeldElsewhere } from "./held-elsewhere";
|
|
15
16
|
|
|
16
17
|
describe("the deep observation envelope", () => {
|
|
17
18
|
test("is discriminated by its version literal", () => {
|
|
@@ -319,6 +320,80 @@ describe("deepValueEqual", () => {
|
|
|
319
320
|
});
|
|
320
321
|
});
|
|
321
322
|
|
|
323
|
+
// #2162 — a `heldElsewhere()` marker is declared on purpose, not authored
|
|
324
|
+
// data to walk into and not an unresolved intrinsic. It must survive
|
|
325
|
+
// normalization as one recognizable leaf, all the way through
|
|
326
|
+
// `flattenDeepProperties` and `deepPathSet`, or `deep-diff.ts` has nothing
|
|
327
|
+
// to key its held classification on.
|
|
328
|
+
describe("normalizeDeepProperties — heldElsewhere() markers (#2162)", () => {
|
|
329
|
+
test("normalizes to a JSON-safe tagged leaf rather than being walked as a two-key object", () => {
|
|
330
|
+
const out = normalizeDeepProperties(
|
|
331
|
+
{ replicas: heldElsewhere<number>({ by: "hpa", reason: "the autoscaler owns replicas after the first apply" }) },
|
|
332
|
+
{ entityType: "Deployment", side: "declared" },
|
|
333
|
+
);
|
|
334
|
+
expect(out).toEqual({
|
|
335
|
+
replicas: { heldElsewhere: HELD_ELSEWHERE_TAG, by: "hpa", reason: "the autoscaler owns replicas after the first apply" },
|
|
336
|
+
});
|
|
337
|
+
expect(isNormalizedHeldElsewhere(out.replicas)).toBe(true);
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
test("is not masked, unresolved, or subjected to a lexicon's own hooks", () => {
|
|
341
|
+
const out = normalizeDeepProperties(
|
|
342
|
+
{ password: heldElsewhere<string>({ by: "operator", reason: "rotated out of band" }) },
|
|
343
|
+
{
|
|
344
|
+
entityType: "T",
|
|
345
|
+
side: "declared",
|
|
346
|
+
// Scoped to the one path under test — a hook that fires on every
|
|
347
|
+
// node (including the root) would mask/unresolve the whole tree,
|
|
348
|
+
// which is a hazard of the hook, not something this test is after.
|
|
349
|
+
hooks: { unresolved: (n) => n.path === "password", mask: (n) => n.path === "password" },
|
|
350
|
+
},
|
|
351
|
+
);
|
|
352
|
+
// If either hook had run ahead of the held check, this would be
|
|
353
|
+
// UNRESOLVED or MASKED instead — the key name looks secret-bearing
|
|
354
|
+
// (`isSensitiveKey`) and both hooks say yes too, and the held check
|
|
355
|
+
// still has to win.
|
|
356
|
+
expect(isNormalizedHeldElsewhere(out.password)).toBe(true);
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
test("nested inside a property-kind declarable, still normalizes to the tagged leaf", () => {
|
|
360
|
+
const propertyDeclarable = (entityType: string, props: Record<string, unknown>) => ({
|
|
361
|
+
entityType,
|
|
362
|
+
kind: "property",
|
|
363
|
+
props,
|
|
364
|
+
});
|
|
365
|
+
const out = normalizeDeepProperties(
|
|
366
|
+
{
|
|
367
|
+
Behavior: propertyDeclarable("HorizontalPodAutoscaler.Behavior", {
|
|
368
|
+
scaleUp: heldElsewhere<Record<string, unknown>>({ by: "hpa", reason: "the controller tunes its own policy" }),
|
|
369
|
+
}),
|
|
370
|
+
},
|
|
371
|
+
{ entityType: "HorizontalPodAutoscaler", side: "declared" },
|
|
372
|
+
);
|
|
373
|
+
expect(isNormalizedHeldElsewhere((out.Behavior as Record<string, unknown>).scaleUp)).toBe(true);
|
|
374
|
+
});
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
describe("flattenDeepProperties — heldElsewhere() markers (#2162)", () => {
|
|
378
|
+
test("addresses the marker as one leaf path, not two", () => {
|
|
379
|
+
const normalized = normalizeDeepProperties(
|
|
380
|
+
{ replicas: heldElsewhere<number>({ by: "hpa", reason: "x" }) },
|
|
381
|
+
{ entityType: "Deployment", side: "declared" },
|
|
382
|
+
);
|
|
383
|
+
const flat = flattenDeepProperties(normalized);
|
|
384
|
+
expect([...flat.keys()]).toEqual(["replicas"]);
|
|
385
|
+
expect(isNormalizedHeldElsewhere(flat.get("replicas"))).toBe(true);
|
|
386
|
+
});
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
describe("deepPathSet — heldElsewhere() markers (#2162)", () => {
|
|
390
|
+
test("records the held property's own path, not synthetic sub-paths into by/reason", () => {
|
|
391
|
+
const marker = heldElsewhere<number>({ by: "hpa", reason: "x" });
|
|
392
|
+
const set = deepPathSet({ replicas: marker });
|
|
393
|
+
expect([...set].sort()).toEqual(["replicas"]);
|
|
394
|
+
});
|
|
395
|
+
});
|
|
396
|
+
|
|
322
397
|
// #1314 — a nested property authored through a lexicon's generated constructor
|
|
323
398
|
// is authored data, not an opaque class instance. Collapsing it to UNRESOLVED
|
|
324
399
|
// left the declared side empty while the live side held the real value, so
|
package/src/deep-observation.ts
CHANGED
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
*/
|
|
45
45
|
|
|
46
46
|
import type { UnobservedEntity } from "./observation";
|
|
47
|
+
import { isHeldElsewhere, isNormalizedHeldElsewhere, normalizeHeldElsewhere } from "./held-elsewhere";
|
|
47
48
|
|
|
48
49
|
/**
|
|
49
50
|
* A live property tree for one declared entity, already normalized by the
|
|
@@ -67,6 +68,23 @@ export interface DeepResourceObservation {
|
|
|
67
68
|
* very different answers to an operator.
|
|
68
69
|
*/
|
|
69
70
|
fieldOwners?: Record<string, string>;
|
|
71
|
+
/**
|
|
72
|
+
* The paths this entity's declaration claims (#2160) — every property chant
|
|
73
|
+
* set, flattened into the diff's own grammar and sorted. Built by core in
|
|
74
|
+
* `lifecycle/deep-observe.ts` from the declaration's `props`, never by a
|
|
75
|
+
* reader: a lexicon has no more to say about it than the props it was handed.
|
|
76
|
+
*
|
|
77
|
+
* It rides here, on the live row, because this is the envelope a consumer
|
|
78
|
+
* holds. With it, a live value classifies three ways instead of two — chant
|
|
79
|
+
* set this and it matches, chant set this and it moved, chant never set it —
|
|
80
|
+
* and only the middle one is drift. Absent for a live entity nobody declared,
|
|
81
|
+
* which has no claim to carry.
|
|
82
|
+
*
|
|
83
|
+
* Complementary to {@link fieldOwners} rather than a replacement: the manager
|
|
84
|
+
* name says *who* holds a field, which is strictly more than "not chant". See
|
|
85
|
+
* `../claimed-fields.ts`.
|
|
86
|
+
*/
|
|
87
|
+
claimedFields?: readonly string[];
|
|
70
88
|
}
|
|
71
89
|
|
|
72
90
|
/**
|
|
@@ -340,6 +358,11 @@ export function deepPathSet(tree: Record<string, unknown>): Set<string> {
|
|
|
340
358
|
out.add(path);
|
|
341
359
|
out.add(pattern);
|
|
342
360
|
}
|
|
361
|
+
// A held marker (#2162) is one declared value, not a `{ by, reason }`
|
|
362
|
+
// object to walk into — same leaf treatment `normalizeDeepProperties`
|
|
363
|
+
// gives it, so this path set agrees with what the normalized tree
|
|
364
|
+
// actually looks like a path down.
|
|
365
|
+
if (isHeldElsewhere(value)) return;
|
|
343
366
|
if (Array.isArray(value)) {
|
|
344
367
|
value.forEach((el, i) => walk(el, joinIndex(path, i), joinPattern(pattern)));
|
|
345
368
|
return;
|
|
@@ -418,6 +441,24 @@ export function normalizeDeepProperties(
|
|
|
418
441
|
};
|
|
419
442
|
|
|
420
443
|
const normalizeValue = (value: unknown, path: string, pattern: string, key: string): unknown => {
|
|
444
|
+
// A `heldElsewhere()` marker (#2162) — declared on purpose, not
|
|
445
|
+
// unresolved and not a plain object to walk into. Checked ahead of even
|
|
446
|
+
// the secret-masking rules below: the marker carries no value at all,
|
|
447
|
+
// only who holds the field and why, so there is nothing for masking to
|
|
448
|
+
// protect and masking it would destroy the one thing worth reporting —
|
|
449
|
+
// a `heldElsewhere()` on a `password`-shaped key ("an operator rotates
|
|
450
|
+
// this out of band") must still say so, not collapse to `[REDACTED]`.
|
|
451
|
+
// Normalized to a JSON-safe tagged leaf so its identity survives this
|
|
452
|
+
// pass and a `--json` round-trip; `deep-diff.ts` reads the tag to
|
|
453
|
+
// report a live difference here as held rather than as drift, on
|
|
454
|
+
// either side (a lexicon's own reader never produces this shape, so
|
|
455
|
+
// the check is safe on the live tree too, though only the declared
|
|
456
|
+
// side ever carries one in practice). Checked ahead of the
|
|
457
|
+
// array/object branches too, same reason a property-Declarable is: it
|
|
458
|
+
// would otherwise be walked as a two-key plain object and lose the
|
|
459
|
+
// very identity that makes it a marker rather than authored data.
|
|
460
|
+
if (isHeldElsewhere(value)) return normalizeHeldElsewhere(value);
|
|
461
|
+
|
|
421
462
|
if (isSensitiveKey(key)) return MASKED;
|
|
422
463
|
// The lexicon's structural mask — same collapse, path-shaped rather than
|
|
423
464
|
// key-named (a k8s Secret's `data.*` no matter what the key is called).
|
|
@@ -426,6 +467,7 @@ export function normalizeDeepProperties(
|
|
|
426
467
|
// expression-string reference — collapses exactly like a class-instance
|
|
427
468
|
// intrinsic does below.
|
|
428
469
|
if (hooks?.unresolved?.(nodeOf(path, pattern, key, value))) return UNRESOLVED;
|
|
470
|
+
|
|
429
471
|
if (isJsonPrimitive(value)) return value;
|
|
430
472
|
|
|
431
473
|
// A PROPERTY-kind Declarable is authored data wearing a class, not an
|
|
@@ -567,6 +609,12 @@ export function flattenDeepProperties(
|
|
|
567
609
|
};
|
|
568
610
|
|
|
569
611
|
const walk = (value: unknown, path: string, pattern: string): void => {
|
|
612
|
+
// A normalized held marker (#2162) is one value, not a two-key object to
|
|
613
|
+
// descend into — same reason UNRESOLVED and a JSON primitive are leaves.
|
|
614
|
+
if (isNormalizedHeldElsewhere(value)) {
|
|
615
|
+
out.set(path, value);
|
|
616
|
+
return;
|
|
617
|
+
}
|
|
570
618
|
if (Array.isArray(value)) {
|
|
571
619
|
if (value.length === 0) {
|
|
572
620
|
out.set(path, []);
|
package/src/detectLexicon.ts
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* The message {@link detectLexicons} throws when a scan of the project's
|
|
5
|
+
* source files turns up no `@intentius/chant-lexicon-*` import at all.
|
|
6
|
+
*
|
|
7
|
+
* Named (chant #2222) because one caller has to tell this failure apart from
|
|
8
|
+
* every other one: `chant lint` reports a lexicon it cannot resolve as an
|
|
9
|
+
* error diagnostic, but "this directory declares no lexicon and imports none"
|
|
10
|
+
* is not that. It is a project that lints under the core rules alone, and it
|
|
11
|
+
* has always been allowed to. See {@link isNoLexiconDetected}.
|
|
12
|
+
*/
|
|
13
|
+
export const NO_LEXICON_DETECTED_MESSAGE = "No lexicon detected in infrastructure files";
|
|
14
|
+
|
|
15
|
+
/** Whether `error` is the {@link NO_LEXICON_DETECTED_MESSAGE} failure. */
|
|
16
|
+
export function isNoLexiconDetected(error: unknown): boolean {
|
|
17
|
+
return error instanceof Error && error.message === NO_LEXICON_DETECTED_MESSAGE;
|
|
18
|
+
}
|
|
19
|
+
|
|
3
20
|
/**
|
|
4
21
|
* Detects which lexicons are being used by analyzing import statements
|
|
5
22
|
* in the provided infrastructure files. Matches any `@intentius/chant-lexicon-*` package.
|
|
@@ -32,7 +49,7 @@ export async function detectLexicons(files: string[]): Promise<string[]> {
|
|
|
32
49
|
|
|
33
50
|
// Validate results
|
|
34
51
|
if (detectedLexicons.size === 0) {
|
|
35
|
-
throw new Error(
|
|
52
|
+
throw new Error(NO_LEXICON_DETECTED_MESSAGE);
|
|
36
53
|
}
|
|
37
54
|
|
|
38
55
|
return Array.from(detectedLexicons);
|
|
@@ -395,8 +395,8 @@ describe("collectEntities with composites", () => {
|
|
|
395
395
|
|
|
396
396
|
describe("collectEntities — default exports (op files)", () => {
|
|
397
397
|
test("two files with `export default` do not collide (keyed per file)", () => {
|
|
398
|
-
const apply = createMockEntity("
|
|
399
|
-
const reconcile = createMockEntity("
|
|
398
|
+
const apply = createMockEntity("Chant::Op");
|
|
399
|
+
const reconcile = createMockEntity("Chant::Op");
|
|
400
400
|
const result = collectEntities([
|
|
401
401
|
{ file: "ops/apply.op.ts", exports: { default: apply } },
|
|
402
402
|
{ file: "ops/reconcile.op.ts", exports: { default: reconcile } },
|
|
@@ -409,7 +409,7 @@ describe("collectEntities — default exports (op files)", () => {
|
|
|
409
409
|
});
|
|
410
410
|
|
|
411
411
|
test("a single default export is collected (not dropped)", () => {
|
|
412
|
-
const op = createMockEntity("
|
|
412
|
+
const op = createMockEntity("Chant::Op");
|
|
413
413
|
const result = collectEntities([{ file: "ops/deploy.op.ts", exports: { default: op } }]);
|
|
414
414
|
expect(result.get("deploy")).toBe(op);
|
|
415
415
|
});
|
package/src/discovery/files.ts
CHANGED
|
@@ -3,10 +3,10 @@ import { existsSync } from "node:fs";
|
|
|
3
3
|
import { join, relative } from "node:path";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* Marker chant writes at the top of files it generates (
|
|
7
|
-
* bootstrap
|
|
8
|
-
* infra source: they hold no Declarables, they self-execute on import
|
|
9
|
-
*
|
|
6
|
+
* Marker chant writes at the top of files it generates (a hosting lexicon's
|
|
7
|
+
* worker/bootstrap output, and the like). Discovery must not treat these as
|
|
8
|
+
* authored infra source: they hold no Declarables, they self-execute on import,
|
|
9
|
+
* and they use runtime patterns the authored-source lint
|
|
10
10
|
* rules forbid (dynamic `process.env[...]` access, spreads). Skipping them keeps
|
|
11
11
|
* `chant lint`/`build` from importing or linting the tool's own output.
|
|
12
12
|
*/
|
|
@@ -1276,7 +1276,7 @@ describe("tryFoldFile — registered authoring helpers (#1082)", () => {
|
|
|
1276
1276
|
stack: "web",
|
|
1277
1277
|
inputs: { pVpcId: { stackOutput: { stack: "shared-foundation", name: "oVpcId" } } },
|
|
1278
1278
|
},
|
|
1279
|
-
{ kind: "gate",
|
|
1279
|
+
{ kind: "gate", gate: "approve", timeout: "24h" },
|
|
1280
1280
|
],
|
|
1281
1281
|
},
|
|
1282
1282
|
],
|
|
@@ -38,7 +38,11 @@ import {
|
|
|
38
38
|
SUPPORTED_UNARY_OPERATORS,
|
|
39
39
|
} from "../fold/subset";
|
|
40
40
|
import { importModule } from "./import";
|
|
41
|
-
import {
|
|
41
|
+
import {
|
|
42
|
+
collectCompositeOrigins,
|
|
43
|
+
collectParamDependencies,
|
|
44
|
+
type CompositeParamScope,
|
|
45
|
+
} from "./param-deps";
|
|
42
46
|
import { setPathProvenance } from "../provenance";
|
|
43
47
|
import { intrinsicCallFoldsEagerly, type IntrinsicDef } from "../lexicon";
|
|
44
48
|
import type { BuildParamValue } from "../build-params";
|
|
@@ -1273,6 +1277,29 @@ interface ResolveCtx {
|
|
|
1273
1277
|
* terminates it — see {@link MAX_INTERPRETATION_DEPTH}.
|
|
1274
1278
|
*/
|
|
1275
1279
|
interpretDepth: number;
|
|
1280
|
+
/**
|
|
1281
|
+
* chant #2161 — the composite whose factory body this context is evaluating,
|
|
1282
|
+
* and how its props are bound there. Present ONLY inside
|
|
1283
|
+
* {@link interpretCompositeFactory}'s body context, so a `new Type(...)` at a
|
|
1284
|
+
* file's own top level records nothing and a nested composite records its own
|
|
1285
|
+
* innermost factory rather than the enclosing one.
|
|
1286
|
+
*/
|
|
1287
|
+
compositeParams?: CompositeParamRecorder;
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
/** chant #2161 — what {@link stampCompositeOrigins} needs at one `new Type(...)` inside a factory body. */
|
|
1291
|
+
interface CompositeParamRecorder {
|
|
1292
|
+
/** The composite's declared name, as `Composite(fn, "<name>")` gave it. */
|
|
1293
|
+
composite: string;
|
|
1294
|
+
/** How the factory's single parameter is bound in this body. */
|
|
1295
|
+
scope: CompositeParamScope;
|
|
1296
|
+
/**
|
|
1297
|
+
* The body's own `const` initializers, so a value hoisted out of a member's
|
|
1298
|
+
* props (`const roleName = \`${props.name}-role\``) is still attributed. The
|
|
1299
|
+
* defining module's top-level consts are layered underneath, exactly as
|
|
1300
|
+
* `fold()` sees them.
|
|
1301
|
+
*/
|
|
1302
|
+
consts: Map<string, ts.Expression>;
|
|
1276
1303
|
}
|
|
1277
1304
|
|
|
1278
1305
|
/** `{ value }` when `node`'s shape was recognized and resolved (value may itself be `undefined`/`null` — e.g. an optional composite member that wasn't created); `undefined` when the shape isn't one the live resolver understands (a plain literal, etc.) — callers fall back to the original, unchanged handling for that shape. */
|
|
@@ -2149,6 +2176,77 @@ function isLiteralPropertyNameNode(node: ts.PropertyName): boolean {
|
|
|
2149
2176
|
return ts.isIdentifier(node) || ts.isStringLiteral(node) || ts.isNumericLiteral(node);
|
|
2150
2177
|
}
|
|
2151
2178
|
|
|
2179
|
+
/**
|
|
2180
|
+
* chant #2161 — how one admissible factory's parameter is bound in its body,
|
|
2181
|
+
* plus the consts an attribution walk has to follow.
|
|
2182
|
+
*
|
|
2183
|
+
* Built from the SOURCE, not from the argument value: the question is which
|
|
2184
|
+
* expression a member's property was written as, not what it evaluated to. A
|
|
2185
|
+
* factory with no parameter at all still gets a recorder, so every path in its
|
|
2186
|
+
* members records as a literal the composite fixes, which is exactly what a
|
|
2187
|
+
* parameterless composite does.
|
|
2188
|
+
*/
|
|
2189
|
+
function compositeParamRecorder(
|
|
2190
|
+
factory: InterpretableFactory,
|
|
2191
|
+
moduleConsts: ReadonlyMap<string, ts.Expression>,
|
|
2192
|
+
): CompositeParamRecorder {
|
|
2193
|
+
const whole = new Set<string>();
|
|
2194
|
+
const destructured = new Map<string, string>();
|
|
2195
|
+
const param = factory.fn.parameters[0];
|
|
2196
|
+
if (param) {
|
|
2197
|
+
if (ts.isIdentifier(param.name)) {
|
|
2198
|
+
whole.add(param.name.text);
|
|
2199
|
+
} else if (ts.isObjectBindingPattern(param.name)) {
|
|
2200
|
+
for (const el of param.name.elements) {
|
|
2201
|
+
const key = bindingElementPropKey(el);
|
|
2202
|
+
if (key !== undefined && ts.isIdentifier(el.name)) destructured.set(el.name.text, key);
|
|
2203
|
+
}
|
|
2204
|
+
}
|
|
2205
|
+
}
|
|
2206
|
+
|
|
2207
|
+
// Body `const`s layered over the defining module's, so a hoisted value is
|
|
2208
|
+
// followed. `interpretCompositeFactory` deletes shadowed names from the
|
|
2209
|
+
// context's own const map as it binds values; this map is separate precisely
|
|
2210
|
+
// so the INITIALIZER stays available to the attribution walk.
|
|
2211
|
+
const consts = new Map(moduleConsts);
|
|
2212
|
+
const body = factory.fn.body;
|
|
2213
|
+
if (ts.isBlock(body)) {
|
|
2214
|
+
for (const statement of body.statements) {
|
|
2215
|
+
if (!ts.isVariableStatement(statement)) continue;
|
|
2216
|
+
for (const decl of statement.declarationList.declarations) {
|
|
2217
|
+
if (ts.isIdentifier(decl.name) && decl.initializer) consts.set(decl.name.text, decl.initializer);
|
|
2218
|
+
}
|
|
2219
|
+
}
|
|
2220
|
+
}
|
|
2221
|
+
|
|
2222
|
+
return { composite: factory.compositeName, scope: { whole, destructured }, consts };
|
|
2223
|
+
}
|
|
2224
|
+
|
|
2225
|
+
/**
|
|
2226
|
+
* chant #2161 — record, for one `new Type({...})` written inside an interpreted
|
|
2227
|
+
* factory body, which factory parameter produced each of its property paths and
|
|
2228
|
+
* which paths the composite fixes.
|
|
2229
|
+
*
|
|
2230
|
+
* Best-effort and additive, exactly like {@link stampParamDependencies}: a
|
|
2231
|
+
* constructor called with no object literal records nothing, and
|
|
2232
|
+
* `setPathProvenance` keeps the first (innermost) writer.
|
|
2233
|
+
*/
|
|
2234
|
+
function stampCompositeOrigins(entity: unknown, node: ts.NewExpression, ctx: ResolveCtx): void {
|
|
2235
|
+
const recorder = ctx.compositeParams;
|
|
2236
|
+
if (!recorder) return;
|
|
2237
|
+
if (typeof entity !== "object" || entity === null) return;
|
|
2238
|
+
let propsArg: ts.ObjectLiteralExpression | undefined;
|
|
2239
|
+
for (const argument of node.arguments ?? []) {
|
|
2240
|
+
if (ts.isObjectLiteralExpression(argument)) {
|
|
2241
|
+
propsArg = argument;
|
|
2242
|
+
break;
|
|
2243
|
+
}
|
|
2244
|
+
}
|
|
2245
|
+
if (!propsArg) return;
|
|
2246
|
+
const origins = collectCompositeOrigins(propsArg, recorder.consts, recorder.scope, recorder.composite);
|
|
2247
|
+
for (const [path, origin] of Object.entries(origins)) setPathProvenance(entity, path, origin);
|
|
2248
|
+
}
|
|
2249
|
+
|
|
2152
2250
|
/**
|
|
2153
2251
|
* Interpret an admissible factory's body against `args`, and assemble the
|
|
2154
2252
|
* result through chant's own {@link Composite}.
|
|
@@ -2196,6 +2294,9 @@ async function interpretCompositeFactory(
|
|
|
2196
2294
|
sandbox: ctx.sandbox,
|
|
2197
2295
|
session: ctx.session,
|
|
2198
2296
|
interpretDepth: ctx.interpretDepth + 1,
|
|
2297
|
+
// chant #2161 — set unconditionally, and NOT inherited from `ctx`: a nested
|
|
2298
|
+
// composite records its own parameters, never the enclosing one's.
|
|
2299
|
+
compositeParams: compositeParamRecorder(factory, scope.consts),
|
|
2199
2300
|
};
|
|
2200
2301
|
|
|
2201
2302
|
const bind = (name: string, value: unknown): void => {
|
|
@@ -2392,7 +2493,9 @@ async function interpretNewExpression(node: ts.NewExpression, ctx: ResolveCtx):
|
|
|
2392
2493
|
|
|
2393
2494
|
const ctorArgs: unknown[] = [];
|
|
2394
2495
|
for (const arg of node.arguments ?? []) ctorArgs.push(await interpretExpression(arg, ctx));
|
|
2395
|
-
|
|
2496
|
+
const instance = new (Ctor as new (...ctorArguments: unknown[]) => unknown)(...ctorArgs);
|
|
2497
|
+
stampCompositeOrigins(instance, node, ctx);
|
|
2498
|
+
return instance;
|
|
2396
2499
|
}
|
|
2397
2500
|
|
|
2398
2501
|
/**
|