@intentius/chant 0.124.52 → 0.124.54
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/discover.d.ts.map +1 -1
- package/dist/audit/discover.js +3 -1
- package/dist/behaviour.d.ts +1 -1
- package/dist/behaviour.d.ts.map +1 -1
- package/dist/capabilities/templates.d.ts +65 -0
- package/dist/capabilities/templates.d.ts.map +1 -0
- package/dist/capabilities/templates.js +193 -0
- package/dist/capabilities/templates.json +145 -0
- package/dist/change-set-graph.d.ts +35 -3
- package/dist/change-set-graph.d.ts.map +1 -1
- package/dist/change-set-graph.js +60 -9
- package/dist/change-set.d.ts +65 -7
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +23 -12
- package/dist/ci-identity.d.ts +7 -2
- package/dist/ci-identity.d.ts.map +1 -1
- package/dist/ci-identity.js +4 -1
- package/dist/cli/commands/import-index.d.ts +52 -0
- package/dist/cli/commands/import-index.d.ts.map +1 -0
- package/dist/cli/commands/import-index.js +226 -0
- package/dist/cli/commands/lint.d.ts.map +1 -1
- package/dist/cli/commands/lint.js +4 -2
- package/dist/cli/handlers/components.d.ts.map +1 -1
- package/dist/cli/handlers/components.js +11 -2
- package/dist/cli/handlers/fan-out.d.ts.map +1 -1
- package/dist/cli/handlers/fan-out.js +16 -3
- package/dist/cli/handlers/graph.d.ts.map +1 -1
- package/dist/cli/handlers/graph.js +22 -4
- package/dist/cli/handlers/index-cloud.d.ts +14 -0
- package/dist/cli/handlers/index-cloud.d.ts.map +1 -0
- package/dist/cli/handlers/index-cloud.js +22 -0
- package/dist/cli/handlers/index-diff.d.ts +18 -0
- package/dist/cli/handlers/index-diff.d.ts.map +1 -0
- package/dist/cli/handlers/index-diff.js +142 -0
- package/dist/cli/handlers/lifecycle-drift.d.ts +25 -0
- package/dist/cli/handlers/lifecycle-drift.d.ts.map +1 -0
- package/dist/cli/handlers/lifecycle-drift.js +64 -0
- package/dist/cli/handlers/lifecycle.d.ts.map +1 -1
- package/dist/cli/handlers/lifecycle.js +188 -28
- package/dist/cli/handlers/misc.d.ts +9 -0
- package/dist/cli/handlers/misc.d.ts.map +1 -1
- package/dist/cli/handlers/misc.js +77 -0
- package/dist/cli/handlers/pr.d.ts.map +1 -1
- package/dist/cli/handlers/pr.js +15 -2
- package/dist/cli/handlers/promote.d.ts.map +1 -1
- package/dist/cli/handlers/promote.js +89 -15
- package/dist/cli/handlers/query.d.ts.map +1 -1
- package/dist/cli/handlers/query.js +28 -4
- package/dist/cli/handlers/scenario.d.ts.map +1 -1
- package/dist/cli/handlers/scenario.js +8 -7
- package/dist/cli/handlers/search.d.ts +34 -4
- package/dist/cli/handlers/search.d.ts.map +1 -1
- package/dist/cli/handlers/search.js +216 -36
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +55 -1
- package/dist/cli/mcp/lifecycle-tools.d.ts.map +1 -1
- package/dist/cli/mcp/lifecycle-tools.js +3 -2
- package/dist/cli/mcp/resource-handlers.d.ts.map +1 -1
- package/dist/cli/mcp/resource-handlers.js +4 -3
- package/dist/cli/mcp/workspace-tools.js +1 -1
- package/dist/cli/parse-args.d.ts.map +1 -1
- package/dist/cli/parse-args.js +55 -2
- package/dist/cli/registry.d.ts +19 -1
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/cloud-lister/aws.d.ts +35 -0
- package/dist/cloud-lister/aws.d.ts.map +1 -0
- package/dist/cloud-lister/aws.js +203 -0
- package/dist/cloud-lister/azure.d.ts +34 -0
- package/dist/cloud-lister/azure.d.ts.map +1 -0
- package/dist/cloud-lister/azure.js +129 -0
- package/dist/cloud-lister/common.d.ts +40 -0
- package/dist/cloud-lister/common.d.ts.map +1 -0
- package/dist/cloud-lister/common.js +83 -0
- package/dist/cloud-lister/credentials.d.ts +50 -0
- package/dist/cloud-lister/credentials.d.ts.map +1 -0
- package/dist/cloud-lister/credentials.js +86 -0
- package/dist/cloud-lister/fakes.d.ts +27 -0
- package/dist/cloud-lister/fakes.d.ts.map +1 -0
- package/dist/cloud-lister/fakes.js +50 -0
- package/dist/cloud-lister/gcp.d.ts +42 -0
- package/dist/cloud-lister/gcp.d.ts.map +1 -0
- package/dist/cloud-lister/gcp.js +143 -0
- package/dist/cloud-lister/guard.d.ts +49 -0
- package/dist/cloud-lister/guard.d.ts.map +1 -0
- package/dist/cloud-lister/guard.js +103 -0
- package/dist/cloud-lister/ids.d.ts +23 -0
- package/dist/cloud-lister/ids.d.ts.map +1 -0
- package/dist/cloud-lister/ids.js +42 -0
- package/dist/cloud-lister/index.d.ts +67 -0
- package/dist/cloud-lister/index.d.ts.map +1 -0
- package/dist/cloud-lister/index.js +102 -0
- package/dist/cloud-lister/kubernetes.d.ts +64 -0
- package/dist/cloud-lister/kubernetes.d.ts.map +1 -0
- package/dist/cloud-lister/kubernetes.js +276 -0
- package/dist/cloud-lister/markers.d.ts +31 -0
- package/dist/cloud-lister/markers.d.ts.map +1 -0
- package/dist/cloud-lister/markers.js +73 -0
- package/dist/cloud-lister/mask.d.ts +31 -0
- package/dist/cloud-lister/mask.d.ts.map +1 -0
- package/dist/cloud-lister/mask.js +74 -0
- package/dist/cloud-lister/sigv4.d.ts +29 -0
- package/dist/cloud-lister/sigv4.d.ts.map +1 -0
- package/dist/cloud-lister/sigv4.js +54 -0
- package/dist/cloud-lister/transport.d.ts +55 -0
- package/dist/cloud-lister/transport.d.ts.map +1 -0
- package/dist/cloud-lister/transport.js +86 -0
- package/dist/cloud-lister/types.d.ts +121 -0
- package/dist/cloud-lister/types.d.ts.map +1 -0
- package/dist/cloud-lister/types.js +24 -0
- package/dist/components/capability-plugin-loader.d.ts.map +1 -1
- package/dist/components/capability-plugin-loader.js +6 -0
- package/dist/components/capability-plugin.d.ts +9 -0
- package/dist/components/capability-plugin.d.ts.map +1 -1
- package/dist/components/capability.d.ts +215 -0
- package/dist/components/capability.d.ts.map +1 -1
- package/dist/components/cli-support.d.ts +21 -0
- package/dist/components/cli-support.d.ts.map +1 -1
- package/dist/components/cli-support.js +58 -14
- package/dist/components/declared-reads.d.ts +38 -0
- package/dist/components/declared-reads.d.ts.map +1 -0
- package/dist/components/declared-reads.js +131 -0
- package/dist/components/deploy-units.d.ts.map +1 -1
- package/dist/components/deploy-units.js +4 -0
- package/dist/components/driver.d.ts +34 -1
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/driver.js +66 -3
- package/dist/components/fan-out-run.d.ts +23 -1
- package/dist/components/fan-out-run.d.ts.map +1 -1
- package/dist/components/fan-out-run.js +82 -14
- package/dist/components/fan-out-support.d.ts +6 -0
- package/dist/components/fan-out-support.d.ts.map +1 -1
- package/dist/components/fan-out-support.js +4 -1
- package/dist/components/fan-out.d.ts +28 -0
- package/dist/components/fan-out.d.ts.map +1 -1
- package/dist/components/groups.d.ts +229 -0
- package/dist/components/groups.d.ts.map +1 -0
- package/dist/components/groups.js +760 -0
- package/dist/components/index.d.ts +6 -2
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +4 -0
- package/dist/components/plan-shape-conformance.d.ts +48 -0
- package/dist/components/plan-shape-conformance.d.ts.map +1 -0
- package/dist/components/plan-shape-conformance.js +122 -0
- package/dist/components/pr-run.d.ts +41 -4
- package/dist/components/pr-run.d.ts.map +1 -1
- package/dist/components/pr-run.js +209 -39
- package/dist/components/promote-rounds.d.ts +9 -0
- package/dist/components/promote-rounds.d.ts.map +1 -1
- package/dist/components/promote-rounds.js +23 -2
- package/dist/components/promote.d.ts +17 -0
- package/dist/components/promote.d.ts.map +1 -1
- package/dist/components/promote.js +36 -6
- package/dist/components/release-gate.d.ts +23 -1
- package/dist/components/release-gate.d.ts.map +1 -1
- package/dist/components/release-gate.js +97 -33
- package/dist/components/run-groups.d.ts +58 -0
- package/dist/components/run-groups.d.ts.map +1 -0
- package/dist/components/run-groups.js +78 -0
- package/dist/components/starter-plugin.d.ts +1 -0
- package/dist/components/starter-plugin.d.ts.map +1 -1
- package/dist/components/starter-plugin.js +6 -1
- package/dist/components/verbs/index.d.ts +1 -0
- package/dist/components/verbs/index.d.ts.map +1 -1
- package/dist/components/verbs/index.js +1 -0
- package/dist/components/verbs/member-outputs.d.ts +187 -0
- package/dist/components/verbs/member-outputs.d.ts.map +1 -0
- package/dist/components/verbs/member-outputs.js +218 -0
- package/dist/config.d.ts +60 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +27 -0
- package/dist/deep-observation.d.ts +1 -13
- package/dist/deep-observation.d.ts.map +1 -1
- package/dist/deep-observation.js +5 -22
- package/dist/drift-record.d.ts +542 -0
- package/dist/drift-record.d.ts.map +1 -0
- package/dist/drift-record.js +886 -0
- package/dist/engine-facts.d.ts +144 -0
- package/dist/engine-facts.d.ts.map +1 -0
- package/dist/engine-facts.js +14 -0
- package/dist/graph-ir.d.ts +153 -2
- package/dist/graph-ir.d.ts.map +1 -1
- package/dist/graph-ir.js +224 -6
- package/dist/graph-refs.d.ts +145 -0
- package/dist/graph-refs.d.ts.map +1 -1
- package/dist/graph-refs.js +305 -0
- package/dist/graph-schema/fixtures/adopt.json +15 -0
- package/dist/graph-schema/fixtures/choudoufu.engine-graph.json +169 -0
- package/dist/graph-schema/fixtures/index.json +68 -0
- package/dist/graph-schema/fixtures/plunge.engine-graph.json +158 -0
- package/dist/graph-schema/fixtures.d.ts +23 -0
- package/dist/graph-schema/fixtures.d.ts.map +1 -0
- package/dist/graph-schema/fixtures.js +246 -0
- package/dist/graph-schema/generate.d.ts +15 -0
- package/dist/graph-schema/generate.d.ts.map +1 -0
- package/dist/graph-schema/generate.js +267 -0
- package/dist/graph-schema/graph.schema.json +1387 -0
- package/dist/health.schema.json +2 -1
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/instance-nodes.d.ts +159 -0
- package/dist/instance-nodes.d.ts.map +1 -0
- package/dist/instance-nodes.js +231 -0
- package/dist/lexicon.d.ts +72 -0
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/lifecycle/adoption-file.d.ts +56 -0
- package/dist/lifecycle/adoption-file.d.ts.map +1 -0
- package/dist/lifecycle/adoption-file.js +123 -0
- package/dist/lifecycle/cloud-index.d.ts +186 -0
- package/dist/lifecycle/cloud-index.d.ts.map +1 -0
- package/dist/lifecycle/cloud-index.js +618 -0
- package/dist/lifecycle/derive-edges.d.ts +59 -0
- package/dist/lifecycle/derive-edges.d.ts.map +1 -0
- package/dist/lifecycle/derive-edges.js +126 -0
- package/dist/lifecycle/git.d.ts +10 -9
- package/dist/lifecycle/git.d.ts.map +1 -1
- package/dist/lifecycle/git.js +7 -1
- package/dist/lifecycle/identity-match.d.ts +133 -0
- package/dist/lifecycle/identity-match.d.ts.map +1 -0
- package/dist/lifecycle/identity-match.js +147 -0
- package/dist/lifecycle/index-diff.d.ts +224 -0
- package/dist/lifecycle/index-diff.d.ts.map +1 -0
- package/dist/lifecycle/index-diff.js +327 -0
- package/dist/lifecycle/index-document.d.ts +130 -0
- package/dist/lifecycle/index-document.d.ts.map +1 -0
- package/dist/lifecycle/index-document.js +189 -0
- package/dist/lifecycle/index-drift.d.ts +121 -0
- package/dist/lifecycle/index-drift.d.ts.map +1 -0
- package/dist/lifecycle/index-drift.js +178 -0
- package/dist/lifecycle/index-import.d.ts +168 -0
- package/dist/lifecycle/index-import.d.ts.map +1 -0
- package/dist/lifecycle/index-import.js +515 -0
- package/dist/lifecycle/index-join.d.ts +129 -0
- package/dist/lifecycle/index-join.d.ts.map +1 -0
- package/dist/lifecycle/index-join.js +248 -0
- package/dist/lifecycle/index.d.ts +4 -0
- package/dist/lifecycle/index.d.ts.map +1 -1
- package/dist/lifecycle/index.js +4 -0
- package/dist/lifecycle/observation-baseline.d.ts +61 -21
- package/dist/lifecycle/observation-baseline.d.ts.map +1 -1
- package/dist/lifecycle/observation-baseline.js +144 -19
- package/dist/lifecycle/observe.d.ts.map +1 -1
- package/dist/lifecycle/observe.js +6 -1
- package/dist/lifecycle/query.d.ts +45 -4
- package/dist/lifecycle/query.d.ts.map +1 -1
- package/dist/lifecycle/query.js +89 -7
- package/dist/lifecycle/replay.d.ts +10 -3
- package/dist/lifecycle/replay.d.ts.map +1 -1
- package/dist/lifecycle/replay.js +10 -6
- package/dist/lifecycle/scenario.d.ts +4 -3
- package/dist/lifecycle/scenario.d.ts.map +1 -1
- package/dist/lifecycle/snapshot-store-fake.d.ts +9 -0
- package/dist/lifecycle/snapshot-store-fake.d.ts.map +1 -0
- package/dist/lifecycle/snapshot-store-fake.js +21 -0
- package/dist/lifecycle/snapshot-store-s3.d.ts +102 -0
- package/dist/lifecycle/snapshot-store-s3.d.ts.map +1 -0
- package/dist/lifecycle/snapshot-store-s3.js +254 -0
- package/dist/lifecycle/snapshot-store.d.ts +170 -0
- package/dist/lifecycle/snapshot-store.d.ts.map +1 -0
- package/dist/lifecycle/snapshot-store.js +832 -0
- package/dist/lifecycle/snapshot.d.ts +11 -0
- package/dist/lifecycle/snapshot.d.ts.map +1 -1
- package/dist/lifecycle/snapshot.js +18 -5
- package/dist/lifecycle/type-listing.d.ts +148 -0
- package/dist/lifecycle/type-listing.d.ts.map +1 -0
- package/dist/lifecycle/type-listing.js +166 -0
- package/dist/lint/component-checks.d.ts +15 -1
- package/dist/lint/component-checks.d.ts.map +1 -1
- package/dist/lint/component-checks.js +1 -0
- package/dist/lint/presets/relaxed.json +2 -1
- package/dist/lint/presets/strict.json +2 -1
- package/dist/lint/rules/__fixtures__/comp/comp008/fail/dns.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp008/fail/dns.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp008/fail/dns.component.js +13 -0
- package/dist/lint/rules/__fixtures__/comp/comp008/pass/dns.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp008/pass/dns.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp008/pass/dns.component.js +8 -0
- package/dist/lint/rules/comp/comp008-applies-signal-only-root.d.ts +33 -0
- package/dist/lint/rules/comp/comp008-applies-signal-only-root.d.ts.map +1 -0
- package/dist/lint/rules/comp/comp008-applies-signal-only-root.js +123 -0
- package/dist/lint/rules/comp/index.d.ts +2 -1
- package/dist/lint/rules/comp/index.d.ts.map +1 -1
- package/dist/lint/rules/comp/index.js +4 -1
- package/dist/observation.d.ts +19 -2
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +18 -1
- package/dist/op/activities/activity-contracts.d.ts +1 -1
- package/dist/op/activities/activity-contracts.js +1 -1
- package/dist/op/activities/change-set.d.ts +6 -4
- package/dist/op/activities/change-set.d.ts.map +1 -1
- package/dist/op/activities/change-set.js +4 -2
- package/dist/op/activity-failure.d.ts +27 -0
- package/dist/op/activity-failure.d.ts.map +1 -1
- package/dist/op/activity-failure.js +31 -0
- package/dist/op/index.d.ts +2 -1
- package/dist/op/index.d.ts.map +1 -1
- package/dist/op/index.js +1 -1
- package/dist/op/local-executor.d.ts +5 -1
- package/dist/op/local-executor.d.ts.map +1 -1
- package/dist/op/local-executor.js +22 -8
- package/dist/pr-loop.d.ts +56 -1
- package/dist/pr-loop.d.ts.map +1 -1
- package/dist/pr-loop.js +51 -1
- package/dist/pulumi-urn.d.ts +101 -0
- package/dist/pulumi-urn.d.ts.map +1 -0
- package/dist/pulumi-urn.js +131 -0
- package/dist/release-floors.d.ts +23 -0
- package/dist/release-floors.d.ts.map +1 -0
- package/dist/release-floors.js +22 -0
- package/dist/sensitive-key.d.ts +23 -0
- package/dist/sensitive-key.d.ts.map +1 -0
- package/dist/sensitive-key.js +31 -0
- package/dist/wave-runtime.mjs +234 -234
- package/dist/workspace/adoption-report.d.ts +53 -0
- package/dist/workspace/adoption-report.d.ts.map +1 -0
- package/dist/workspace/adoption-report.js +76 -0
- package/dist/workspace/capabilities-contract.d.ts +7 -0
- package/dist/workspace/capabilities-contract.d.ts.map +1 -1
- package/dist/workspace/capabilities-contract.js +2 -1
- package/dist/workspace/capabilities.schema.json +98 -0
- package/dist/workspace/change-set.schema.json +42 -3
- package/dist/workspace/ci-cloud-identity.d.ts +13 -1
- package/dist/workspace/ci-cloud-identity.d.ts.map +1 -1
- package/dist/workspace/ci-cloud-identity.js +30 -1
- package/dist/workspace/compose-graph.d.ts +10 -1
- package/dist/workspace/compose-graph.d.ts.map +1 -1
- package/dist/workspace/compose-graph.js +6 -1
- package/dist/workspace/conformance/index.d.ts +1 -1
- package/dist/workspace/conformance/index.d.ts.map +1 -1
- package/dist/workspace/conformance/index.js +6 -1
- package/dist/workspace/drift-cli.d.ts +81 -0
- package/dist/workspace/drift-cli.d.ts.map +1 -0
- package/dist/workspace/drift-cli.js +317 -0
- package/dist/workspace/drift.schema.json +672 -0
- package/dist/workspace/graph-cli.d.ts +2 -0
- package/dist/workspace/graph-cli.d.ts.map +1 -1
- package/dist/workspace/graph-cli.js +3 -0
- package/dist/workspace/graph.schema.json +72 -0
- package/dist/workspace/init.d.ts +5 -1
- package/dist/workspace/init.d.ts.map +1 -1
- package/dist/workspace/init.js +55 -9
- package/dist/workspace/ledger.schema.json +1 -1
- package/dist/workspace/nested-graph.d.ts.map +1 -1
- package/dist/workspace/nested-graph.js +2 -0
- package/dist/workspace/pr-report.schema.json +51 -2
- package/dist/workspace/promote-waves.d.ts +112 -0
- package/dist/workspace/promote-waves.d.ts.map +1 -0
- package/dist/workspace/promote-waves.js +290 -0
- package/dist/workspace/promote.d.ts +84 -2
- package/dist/workspace/promote.d.ts.map +1 -1
- package/dist/workspace/promote.js +347 -61
- package/dist/workspace/reason-codes.d.ts +12 -0
- package/dist/workspace/reason-codes.d.ts.map +1 -1
- package/dist/workspace/reason-codes.js +14 -0
- package/dist/workspace/search-contract.d.ts +3 -3
- package/dist/workspace/search-contract.d.ts.map +1 -1
- package/dist/workspace/search-contract.js +2 -0
- package/dist/workspace/search.schema.json +103 -5
- package/package.json +14 -1
- package/src/__fixtures__/drift-record/README.md +58 -0
- package/src/__fixtures__/drift-record/choudoufu-cone.ndjson +4 -0
- package/src/__fixtures__/drift-record/choudoufu-resource.ndjson +3 -0
- package/src/__fixtures__/drift-record/component-status-ledger.json +65 -0
- package/src/__fixtures__/drift-record/component-status.json +91 -0
- package/src/__fixtures__/drift-record/deep-diff.json +259 -0
- package/src/__fixtures__/drift-record/lifecycle-diff-live.json +825 -0
- package/src/__fixtures__/drift-record/live-diff.json +125 -0
- package/src/audit/discover.e2e.test.ts +14 -0
- package/src/audit/discover.ts +3 -1
- package/src/behaviour.ts +1 -1
- package/src/capabilities/templates.json +145 -0
- package/src/capabilities/templates.test.ts +212 -0
- package/src/capabilities/templates.ts +204 -0
- package/src/change-set-bundle.test.ts +83 -0
- package/src/change-set-graph.ts +80 -9
- package/src/change-set.test.ts +24 -0
- package/src/change-set.ts +77 -14
- package/src/ci-identity-targets.test.ts +23 -0
- package/src/ci-identity.ts +10 -4
- package/src/cli/commands/import-index.test.ts +117 -0
- package/src/cli/commands/import-index.ts +265 -0
- package/src/cli/commands/lint.ts +4 -2
- package/src/cli/handlers/components.test.ts +9 -0
- package/src/cli/handlers/components.ts +12 -2
- package/src/cli/handlers/fan-out.ts +17 -3
- package/src/cli/handlers/graph.test.ts +42 -0
- package/src/cli/handlers/graph.ts +26 -4
- package/src/cli/handlers/index-cloud.ts +32 -0
- package/src/cli/handlers/index-diff.test.ts +68 -0
- package/src/cli/handlers/index-diff.ts +146 -0
- package/src/cli/handlers/ledger-root-member.test.ts +161 -0
- package/src/cli/handlers/lifecycle-drift.ts +68 -0
- package/src/cli/handlers/lifecycle.test.ts +33 -11
- package/src/cli/handlers/lifecycle.ts +205 -30
- package/src/cli/handlers/misc.ts +73 -0
- package/src/cli/handlers/pr-waves-blocked.test.ts +37 -2
- package/src/cli/handlers/pr.ts +14 -2
- package/src/cli/handlers/promote.test.ts +64 -0
- package/src/cli/handlers/promote.ts +81 -6
- package/src/cli/handlers/query.ts +27 -4
- package/src/cli/handlers/run-declared-reads-cli.test.ts +187 -0
- package/src/cli/handlers/run-groups-cli.test.ts +229 -0
- package/src/cli/handlers/scenario.test.ts +13 -0
- package/src/cli/handlers/scenario.ts +8 -7
- package/src/cli/handlers/search-index.test.ts +255 -0
- package/src/cli/handlers/search-json.test.ts +1 -1
- package/src/cli/handlers/search-ownership.test.ts +194 -0
- package/src/cli/handlers/search.ts +271 -38
- package/src/cli/main.test.ts +7 -0
- package/src/cli/main.ts +56 -1
- package/src/cli/mcp/lifecycle-tools.ts +3 -2
- package/src/cli/mcp/resource-handlers.ts +4 -3
- package/src/cli/mcp/workspace-tools.ts +1 -1
- package/src/cli/parse-args.ts +40 -2
- package/src/cli/registry.ts +19 -1
- package/src/cloud-lister/aws.test.ts +202 -0
- package/src/cloud-lister/aws.ts +226 -0
- package/src/cloud-lister/azure.test.ts +132 -0
- package/src/cloud-lister/azure.ts +142 -0
- package/src/cloud-lister/common.ts +115 -0
- package/src/cloud-lister/credentials.ts +110 -0
- package/src/cloud-lister/fakes.ts +66 -0
- package/src/cloud-lister/gcp.test.ts +121 -0
- package/src/cloud-lister/gcp.ts +159 -0
- package/src/cloud-lister/guard.test.ts +198 -0
- package/src/cloud-lister/guard.ts +111 -0
- package/src/cloud-lister/ids.ts +54 -0
- package/src/cloud-lister/index.ts +134 -0
- package/src/cloud-lister/kubernetes.test.ts +160 -0
- package/src/cloud-lister/kubernetes.ts +284 -0
- package/src/cloud-lister/markers.ts +74 -0
- package/src/cloud-lister/mask.ts +77 -0
- package/src/cloud-lister/shape.test.ts +81 -0
- package/src/cloud-lister/sigv4.ts +70 -0
- package/src/cloud-lister/transport.ts +118 -0
- package/src/cloud-lister/types.ts +135 -0
- package/src/components/capability-plugin-loader.ts +4 -0
- package/src/components/capability-plugin.ts +10 -0
- package/src/components/capability.ts +229 -0
- package/src/components/cli-support.ts +70 -14
- package/src/components/declared-reads.test.ts +103 -0
- package/src/components/declared-reads.ts +134 -0
- package/src/components/deploy-units.ts +4 -0
- package/src/components/driver.ts +89 -4
- package/src/components/fan-out-run.ts +95 -15
- package/src/components/fan-out-support.ts +10 -1
- package/src/components/fan-out.ts +30 -0
- package/src/components/groups.test.ts +320 -0
- package/src/components/groups.ts +880 -0
- package/src/components/index.ts +42 -0
- package/src/components/plan-shape-conformance.ts +130 -0
- package/src/components/pr-env-run-bundle.test.ts +2 -0
- package/src/components/pr-run.test.ts +516 -3
- package/src/components/pr-run.ts +231 -41
- package/src/components/promote-rounds.ts +25 -2
- package/src/components/promote.ts +55 -5
- package/src/components/registry.test.ts +1 -1
- package/src/components/release-gate.ts +115 -30
- package/src/components/release-groups.test.ts +362 -0
- package/src/components/run-groups.ts +113 -0
- package/src/components/starter-plugin.ts +6 -0
- package/src/components/verbs/index.ts +1 -0
- package/src/components/verbs/member-outputs.test.ts +205 -0
- package/src/components/verbs/member-outputs.ts +308 -0
- package/src/config.ts +44 -0
- package/src/deep-observation.ts +5 -23
- package/src/drift-record.test.ts +596 -0
- package/src/drift-record.ts +1206 -0
- package/src/engine-facts.guard.test.ts +111 -0
- package/src/engine-facts.test.ts +178 -0
- package/src/engine-facts.ts +154 -0
- package/src/gated-waves-bundle.test.ts +2 -0
- package/src/graph-ir-live.test.ts +92 -0
- package/src/graph-ir.ts +317 -7
- package/src/graph-refs.ts +416 -0
- package/src/graph-schema/fixtures/adopt.json +15 -0
- package/src/graph-schema/fixtures/choudoufu.engine-graph.json +169 -0
- package/src/graph-schema/fixtures/index.json +68 -0
- package/src/graph-schema/fixtures/plunge.engine-graph.json +158 -0
- package/src/graph-schema/fixtures.ts +267 -0
- package/src/graph-schema/generate.ts +263 -0
- package/src/graph-schema/graph-schema.test.ts +153 -0
- package/src/graph-schema/graph.schema.json +1387 -0
- package/src/health.schema.json +2 -1
- package/src/identity.ts +2 -0
- package/src/index.ts +2 -0
- package/src/instance-nodes.ts +288 -0
- package/src/lexicon.ts +76 -0
- package/src/lifecycle/__fixtures__/index-diff/20261026T120000Z-aaaaaaaaaaaa.json +149 -0
- package/src/lifecycle/__fixtures__/index-diff/20261026T130000Z-bbbbbbbbbbbb.json +127 -0
- package/src/lifecycle/adoption-file.test.ts +100 -0
- package/src/lifecycle/adoption-file.ts +154 -0
- package/src/lifecycle/cloud-index.test.ts +517 -0
- package/src/lifecycle/cloud-index.ts +736 -0
- package/src/lifecycle/derive-edges.test.ts +193 -0
- package/src/lifecycle/derive-edges.ts +182 -0
- package/src/lifecycle/git.ts +10 -4
- package/src/lifecycle/identity-match.test.ts +308 -0
- package/src/lifecycle/identity-match.ts +257 -0
- package/src/lifecycle/index-diff.test.ts +198 -0
- package/src/lifecycle/index-diff.ts +476 -0
- package/src/lifecycle/index-document.test.ts +64 -0
- package/src/lifecycle/index-document.ts +299 -0
- package/src/lifecycle/index-drift.test.ts +191 -0
- package/src/lifecycle/index-drift.ts +304 -0
- package/src/lifecycle/index-import.test.ts +255 -0
- package/src/lifecycle/index-import.ts +634 -0
- package/src/lifecycle/index-join.test.ts +250 -0
- package/src/lifecycle/index-join.ts +304 -0
- package/src/lifecycle/index-store-load-bearing.test.ts +187 -0
- package/src/lifecycle/index.ts +4 -0
- package/src/lifecycle/member-ledger.test.ts +25 -7
- package/src/lifecycle/observation-baseline.test.ts +72 -1
- package/src/lifecycle/observation-baseline.ts +190 -27
- package/src/lifecycle/observe.ts +6 -1
- package/src/lifecycle/query.test.ts +69 -1
- package/src/lifecycle/query.ts +103 -10
- package/src/lifecycle/replay.test.ts +9 -5
- package/src/lifecycle/replay.ts +9 -5
- package/src/lifecycle/scenario.ts +4 -3
- package/src/lifecycle/snapshot-store-fake.ts +29 -0
- package/src/lifecycle/snapshot-store-s3.ts +316 -0
- package/src/lifecycle/snapshot-store.test.ts +385 -0
- package/src/lifecycle/snapshot-store.ts +981 -0
- package/src/lifecycle/snapshot.test.ts +13 -0
- package/src/lifecycle/snapshot.ts +23 -6
- package/src/lifecycle/type-listing.test.ts +166 -0
- package/src/lifecycle/type-listing.ts +309 -0
- package/src/lint/component-checks.ts +17 -1
- package/src/lint/config.test.ts +3 -0
- package/src/lint/presets/relaxed.json +2 -1
- package/src/lint/presets/strict.json +2 -1
- package/src/lint/rules/__fixtures__/comp/comp008/fail/dns.component.ts +15 -0
- package/src/lint/rules/__fixtures__/comp/comp008/pass/dns.component.ts +10 -0
- package/src/lint/rules/comp/comp.test.ts +2 -1
- package/src/lint/rules/comp/comp008-applies-signal-only-root.ts +121 -0
- package/src/lint/rules/comp/comp008.test.ts +77 -0
- package/src/lint/rules/comp/index.ts +4 -1
- package/src/observation-edges.test.ts +33 -0
- package/src/observation.ts +36 -1
- package/src/op/activities/activity-contracts.ts +1 -1
- package/src/op/activities/change-set.ts +8 -5
- package/src/op/activity-failure.ts +36 -0
- package/src/op/index.ts +2 -1
- package/src/op/local-executor.test.ts +80 -0
- package/src/op/local-executor.ts +27 -9
- package/src/pr-loop-bundle.test.ts +5 -2
- package/src/pr-loop.test.ts +43 -0
- package/src/pr-loop.ts +111 -2
- package/src/pulumi-urn.ts +151 -0
- package/src/release-floors.ts +22 -0
- package/src/sensitive-key.ts +34 -0
- package/src/workspace/adoption-report.test.ts +61 -0
- package/src/workspace/adoption-report.ts +103 -0
- package/src/workspace/capabilities-contract.test.ts +4 -0
- package/src/workspace/capabilities-contract.ts +9 -1
- package/src/workspace/capabilities.schema.json +98 -0
- package/src/workspace/change-set.schema.json +42 -3
- package/src/workspace/ci-cloud-identity.ts +31 -1
- package/src/workspace/compose-graph.test.ts +12 -0
- package/src/workspace/compose-graph.ts +12 -1
- package/src/workspace/conformance/conformance.e2e.test.ts +2 -1
- package/src/workspace/conformance/index.ts +6 -1
- package/src/workspace/drift-cli.test.ts +65 -0
- package/src/workspace/drift-cli.ts +365 -0
- package/src/workspace/drift.schema.json +672 -0
- package/src/workspace/graph-cli.ts +5 -0
- package/src/workspace/graph.schema.json +72 -0
- package/src/workspace/init.test.ts +38 -1
- package/src/workspace/init.ts +50 -8
- package/src/workspace/intent-gaps.test.ts +18 -2
- package/src/workspace/ledger.schema.json +1 -1
- package/src/workspace/nested-graph.ts +1 -0
- package/src/workspace/pr-report.schema.json +51 -2
- package/src/workspace/promote-waves.test.ts +296 -0
- package/src/workspace/promote-waves.ts +340 -0
- package/src/workspace/promote.test.ts +158 -4
- package/src/workspace/promote.ts +398 -57
- package/src/workspace/reason-codes.test.ts +4 -1
- package/src/workspace/reason-codes.ts +14 -0
- package/src/workspace/search-contract.ts +2 -0
- package/src/workspace/search.schema.json +103 -5
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `chant index diff <a> [<b>] [--store <spec>] [--json]` (#4533): what
|
|
3
|
+
* changed between two versions of one index scope.
|
|
4
|
+
*
|
|
5
|
+
* `<a>` is `<scopeKey>/<version>`, or `<scopeKey>` alone. `<b>` is
|
|
6
|
+
* `<scopeKey>/<version>`, or a version name in `<a>`'s scope. With no `<b>`,
|
|
7
|
+
* the version before `<a>` is diffed against `<a>`, and a scope alone diffs
|
|
8
|
+
* its last two versions.
|
|
9
|
+
*
|
|
10
|
+
* Versions are read through #4519's store API, from the store `chant index`
|
|
11
|
+
* writes to (#4532's {@link planIndexStore}: `--store <spec>`, else the
|
|
12
|
+
* project's store, else the per-user one), so a git-ref, local or s3 store
|
|
13
|
+
* diffs the same way. Nothing is built, no lexicon is loaded and no cloud is
|
|
14
|
+
* queried. The computation is ../../lifecycle/index-diff.ts.
|
|
15
|
+
*/
|
|
16
|
+
import { homedir } from "node:os";
|
|
17
|
+
import { chantUserStoreDir, IndexUsageError, planIndexStore } from "../../lifecycle/cloud-index.js";
|
|
18
|
+
import { diffIndexVersionRefs, IndexScopeMismatch, NotAnIndexVersion, parseIndexVersionRef } from "../../lifecycle/index-diff.js";
|
|
19
|
+
import { createSnapshotStore, resolveSnapshotStore, snapshotStoreConfig } from "../../lifecycle/snapshot-store.js";
|
|
20
|
+
export const INDEX_DIFF_USAGE = `chant index diff <a> [<b>] [--store <spec>] [--json]
|
|
21
|
+
|
|
22
|
+
What changed between two versions of one index scope: nodes added and
|
|
23
|
+
removed, properties changed, edges added and removed. A node is removed only
|
|
24
|
+
where the later read listed its type and location; elsewhere it is not
|
|
25
|
+
observed. Two versions of different scopes are refused.
|
|
26
|
+
|
|
27
|
+
<a> <scopeKey>/<version>, or <scopeKey> for its latest version
|
|
28
|
+
<b> <scopeKey>/<version>, or a version name in <a>'s scope.
|
|
29
|
+
Absent: the version before <a> against <a> (a scope alone:
|
|
30
|
+
its last two versions)
|
|
31
|
+
--store <spec> the store to read, as chant index takes it (local,
|
|
32
|
+
local:<dir>, git-ref, git-ref:<ref>, s3,
|
|
33
|
+
s3://<bucket>[/<prefix>]). Default: the project's store,
|
|
34
|
+
else chant's per-user store
|
|
35
|
+
--json the diff as JSON
|
|
36
|
+
`;
|
|
37
|
+
async function openReadStore(plan, cwd) {
|
|
38
|
+
switch (plan.kind) {
|
|
39
|
+
case "user":
|
|
40
|
+
return createSnapshotStore({ store: "local", dir: plan.dir }, { cwd });
|
|
41
|
+
case "project":
|
|
42
|
+
return resolveSnapshotStore({ cwd: plan.projectDir });
|
|
43
|
+
case "spec":
|
|
44
|
+
return createSnapshotStore(snapshotStoreConfig(plan.configured, plan.env), { cwd, env: plan.env });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const show = (v) => (v === undefined ? "(absent)" : JSON.stringify(v));
|
|
48
|
+
/** The diff as text, one line per change. */
|
|
49
|
+
export function renderIndexDiff(d) {
|
|
50
|
+
const lines = [];
|
|
51
|
+
lines.push(`Index diff: ${d.scopeKey}`);
|
|
52
|
+
lines.push(` from ${d.from.version ?? d.from.digest.slice(0, 12)} (observed ${d.from.observedAt})`);
|
|
53
|
+
lines.push(` to ${d.to.version ?? d.to.digest.slice(0, 12)} (observed ${d.to.observedAt})`);
|
|
54
|
+
if (d.unchanged) {
|
|
55
|
+
lines.push("", "Same digest: nothing changed.");
|
|
56
|
+
return `${lines.join("\n")}\n`;
|
|
57
|
+
}
|
|
58
|
+
const c = d.counts;
|
|
59
|
+
lines.push("", `${c.added} added, ${c.removed} removed, ${c.changed} changed (${c.properties} properties), ${c.notObserved} not observed; edges ${c.edgesAdded} added, ${c.edgesRemoved} removed, ${c.edgesNotObserved} not observed`);
|
|
60
|
+
for (const n of d.nodes.added)
|
|
61
|
+
lines.push(` + ${n.key}`);
|
|
62
|
+
for (const n of d.nodes.removed)
|
|
63
|
+
lines.push(` - ${n.key}`);
|
|
64
|
+
for (const n of d.nodes.changed) {
|
|
65
|
+
lines.push(` ~ ${n.key}`);
|
|
66
|
+
for (const p of n.properties)
|
|
67
|
+
lines.push(` ${p.path}: ${show(p.before)} -> ${show(p.after)}`);
|
|
68
|
+
}
|
|
69
|
+
for (const n of d.nodes.notObserved)
|
|
70
|
+
lines.push(` ? ${n.key} (not observed in the ${n.side} read: ${n.verdict}${n.detail ? `, ${n.detail}` : ""})`);
|
|
71
|
+
for (const e of d.edges.added)
|
|
72
|
+
lines.push(` + edge ${e.from} -> ${e.to}${e.viaAttr ? ` via ${e.viaAttr}` : ""}`);
|
|
73
|
+
for (const e of d.edges.removed)
|
|
74
|
+
lines.push(` - edge ${e.from} -> ${e.to}${e.viaAttr ? ` via ${e.viaAttr}` : ""}`);
|
|
75
|
+
for (const e of d.edges.notObserved)
|
|
76
|
+
lines.push(` ? edge ${e.from} -> ${e.to} (${e.unobservedEnd} not observed in the ${e.side} read: ${e.verdict})`);
|
|
77
|
+
for (const v of d.coverage)
|
|
78
|
+
lines.push(` coverage ${v.listedType} @ ${v.location}: ${v.before ?? "(none)"} -> ${v.after ?? "(none)"}`);
|
|
79
|
+
return `${lines.join("\n")}\n`;
|
|
80
|
+
}
|
|
81
|
+
/** `chant index diff`'s argv (the words after `diff`). Exit 0 on a diff, 1 on a refusal, 2 on a usage error. */
|
|
82
|
+
export async function runIndexDiff(argv, o = {}) {
|
|
83
|
+
const out = o.stdout ?? ((s) => void process.stdout.write(s));
|
|
84
|
+
const err = o.stderr ?? ((s) => void process.stderr.write(s));
|
|
85
|
+
const cwd = o.cwd ?? process.cwd();
|
|
86
|
+
const env = o.env ?? process.env;
|
|
87
|
+
if (argv.includes("-h") || argv.includes("--help")) {
|
|
88
|
+
out(INDEX_DIFF_USAGE);
|
|
89
|
+
return 0;
|
|
90
|
+
}
|
|
91
|
+
const refs = [];
|
|
92
|
+
let store;
|
|
93
|
+
let json = false;
|
|
94
|
+
for (let i = 0; i < argv.length; i++) {
|
|
95
|
+
const a = argv[i];
|
|
96
|
+
if (a === "--json")
|
|
97
|
+
json = true;
|
|
98
|
+
else if (a === "--store") {
|
|
99
|
+
store = argv[++i];
|
|
100
|
+
if (!store || store.startsWith("-")) {
|
|
101
|
+
err(`chant index diff: --store needs a store spec\n\n${INDEX_DIFF_USAGE}`);
|
|
102
|
+
return 2;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
else if (a.startsWith("--store="))
|
|
106
|
+
store = a.slice("--store=".length);
|
|
107
|
+
else if (a.startsWith("-")) {
|
|
108
|
+
err(`chant index diff: unknown flag ${a}\n\n${INDEX_DIFF_USAGE}`);
|
|
109
|
+
return 2;
|
|
110
|
+
}
|
|
111
|
+
else
|
|
112
|
+
refs.push(a);
|
|
113
|
+
}
|
|
114
|
+
if (refs.length < 1 || refs.length > 2) {
|
|
115
|
+
err(`chant index diff: name one or two index versions\n\n${INDEX_DIFF_USAGE}`);
|
|
116
|
+
return 2;
|
|
117
|
+
}
|
|
118
|
+
let d;
|
|
119
|
+
try {
|
|
120
|
+
const from = parseIndexVersionRef(refs[0]);
|
|
121
|
+
const to = refs[1] ? parseIndexVersionRef(refs[1], from.scopeKey) : undefined;
|
|
122
|
+
const plan = planIndexStore({ store, cwd, env, defaultStoreDir: () => chantUserStoreDir(env, o.home ?? homedir()), command: "chant index diff" });
|
|
123
|
+
const s = await (o.openStore ?? openReadStore)(plan, cwd);
|
|
124
|
+
await s.fetch();
|
|
125
|
+
d = await diffIndexVersionRefs(s, from, to);
|
|
126
|
+
}
|
|
127
|
+
catch (e) {
|
|
128
|
+
if (e instanceof IndexUsageError) {
|
|
129
|
+
err(`${e.message}\n`);
|
|
130
|
+
return 2;
|
|
131
|
+
}
|
|
132
|
+
if (e instanceof IndexScopeMismatch || e instanceof NotAnIndexVersion) {
|
|
133
|
+
if (json)
|
|
134
|
+
out(`${JSON.stringify({ error: e.code, message: e.message, ...(e instanceof IndexScopeMismatch ? { fromScopeKey: e.fromScopeKey, toScopeKey: e.toScopeKey } : {}) }, null, 2)}\n`);
|
|
135
|
+
err(`chant index diff: ${e.message}\n`);
|
|
136
|
+
return 1;
|
|
137
|
+
}
|
|
138
|
+
throw e;
|
|
139
|
+
}
|
|
140
|
+
out(json ? `${JSON.stringify(d, null, 2)}\n` : renderIndexDiff(d));
|
|
141
|
+
return 0;
|
|
142
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `chant lifecycle drift [--member <name>] [--read <read>] [--resource <addr>]`
|
|
3
|
+
* (behold#995): the project's drift, as each lexicon's own engine reads it,
|
|
4
|
+
* printed as the drift-record NDJSON stream (`../../drift-record.ts`).
|
|
5
|
+
*
|
|
6
|
+
* This is the member half of `chant workspace drift`. A `terraform` or
|
|
7
|
+
* `choudoufu` member has no chant config of its own, so the workspace writes
|
|
8
|
+
* it a reader project (`../../workspace/kind-readers.ts`) and runs this
|
|
9
|
+
* command there, under the member's own toolchain, the way `workspace graph`
|
|
10
|
+
* runs `chant graph`. Every lexicon with a `readDrift` is asked; the lines
|
|
11
|
+
* are printed in the order they came, one JSON object per line. chant core
|
|
12
|
+
* never imports a lexicon to read drift.
|
|
13
|
+
*
|
|
14
|
+
* `--member` names the workspace member the records are for; it defaults to
|
|
15
|
+
* the project directory's name. A lexicon that refuses the read (a read its
|
|
16
|
+
* engine has not got, or one resource on an engine that cannot read one on
|
|
17
|
+
* its own) makes the command print `{"refused": {code, message}}` as its
|
|
18
|
+
* only stdout line and exit 3, so the workspace command can name the
|
|
19
|
+
* refusal. No lexicon with a drift read is the refusal `no-drift-read`.
|
|
20
|
+
*/
|
|
21
|
+
import type { CommandContext } from "../registry.js";
|
|
22
|
+
/** The exit status of a refused read. */
|
|
23
|
+
export declare const DRIFT_REFUSED_EXIT = 3;
|
|
24
|
+
export declare function runLifecycleDrift(ctx: CommandContext): Promise<number>;
|
|
25
|
+
//# sourceMappingURL=lifecycle-drift.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle-drift.d.ts","sourceRoot":"","sources":["../../../src/cli/handlers/lifecycle-drift.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,yCAAyC;AACzC,eAAO,MAAM,kBAAkB,IAAI,CAAC;AASpC,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA8B5E"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `chant lifecycle drift [--member <name>] [--read <read>] [--resource <addr>]`
|
|
3
|
+
* (behold#995): the project's drift, as each lexicon's own engine reads it,
|
|
4
|
+
* printed as the drift-record NDJSON stream (`../../drift-record.ts`).
|
|
5
|
+
*
|
|
6
|
+
* This is the member half of `chant workspace drift`. A `terraform` or
|
|
7
|
+
* `choudoufu` member has no chant config of its own, so the workspace writes
|
|
8
|
+
* it a reader project (`../../workspace/kind-readers.ts`) and runs this
|
|
9
|
+
* command there, under the member's own toolchain, the way `workspace graph`
|
|
10
|
+
* runs `chant graph`. Every lexicon with a `readDrift` is asked; the lines
|
|
11
|
+
* are printed in the order they came, one JSON object per line. chant core
|
|
12
|
+
* never imports a lexicon to read drift.
|
|
13
|
+
*
|
|
14
|
+
* `--member` names the workspace member the records are for; it defaults to
|
|
15
|
+
* the project directory's name. A lexicon that refuses the read (a read its
|
|
16
|
+
* engine has not got, or one resource on an engine that cannot read one on
|
|
17
|
+
* its own) makes the command print `{"refused": {code, message}}` as its
|
|
18
|
+
* only stdout line and exit 3, so the workspace command can name the
|
|
19
|
+
* refusal. No lexicon with a drift read is the refusal `no-drift-read`.
|
|
20
|
+
*/
|
|
21
|
+
import { basename, resolve } from "node:path";
|
|
22
|
+
import { loadChantConfig } from "../../config.js";
|
|
23
|
+
import { DRIFT_READS, encodeDriftLine } from "../../drift-record.js";
|
|
24
|
+
import { formatError } from "../format.js";
|
|
25
|
+
/** The exit status of a refused read. */
|
|
26
|
+
export const DRIFT_REFUSED_EXIT = 3;
|
|
27
|
+
const USAGE = "chant lifecycle drift [--member <name>] [--read <state|plan|refresh|live-read|ownership>] [--resource <addr>]";
|
|
28
|
+
function refuse(code, message) {
|
|
29
|
+
console.log(JSON.stringify({ refused: { code, message } }));
|
|
30
|
+
return DRIFT_REFUSED_EXIT;
|
|
31
|
+
}
|
|
32
|
+
export async function runLifecycleDrift(ctx) {
|
|
33
|
+
const { args, plugins } = ctx;
|
|
34
|
+
const read = args.driftRead;
|
|
35
|
+
if (read !== undefined && !DRIFT_READS.includes(read)) {
|
|
36
|
+
console.error(formatError({ message: `--read ${read} is not a drift read; the reads are ${DRIFT_READS.join(", ")}`, hint: USAGE }));
|
|
37
|
+
return 1;
|
|
38
|
+
}
|
|
39
|
+
const projectRoot = resolve(".");
|
|
40
|
+
const { config } = await loadChantConfig(projectRoot);
|
|
41
|
+
const member = args.members?.[0] ?? basename(projectRoot);
|
|
42
|
+
const readers = plugins.filter((p) => typeof p.readDrift === "function");
|
|
43
|
+
if (readers.length === 0) {
|
|
44
|
+
return refuse("no-drift-read", `no lexicon this project declares (${plugins.map((p) => p.name).join(", ") || "none"}) has a drift read`);
|
|
45
|
+
}
|
|
46
|
+
const observedAt = new Date().toISOString();
|
|
47
|
+
const lines = [];
|
|
48
|
+
for (const plugin of readers) {
|
|
49
|
+
const answer = await plugin.readDrift({
|
|
50
|
+
member,
|
|
51
|
+
projectRoot,
|
|
52
|
+
config: config,
|
|
53
|
+
...(read !== undefined ? { read: read } : {}),
|
|
54
|
+
...(args.resource !== undefined ? { resource: args.resource } : {}),
|
|
55
|
+
observedAt,
|
|
56
|
+
});
|
|
57
|
+
if ("refused" in answer)
|
|
58
|
+
return refuse(answer.refused.code, `${plugin.name}: ${answer.refused.message}`);
|
|
59
|
+
lines.push(...answer.lines);
|
|
60
|
+
}
|
|
61
|
+
for (const line of lines)
|
|
62
|
+
process.stdout.write(encodeDriftLine(line));
|
|
63
|
+
return 0;
|
|
64
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../../src/cli/handlers/lifecycle.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../../src/cli/handlers/lifecycle.ts"],"names":[],"mappings":"AAkDA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAKlD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAKhD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,GAAG,MAAM,CAE9E;AAED;;cAEc;AACd,UAAU,WAAW;IACnB;iDAC6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;0CACsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb;;;6DAGyD;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,GAAG,WAAW,EAAE,CAMxF;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA8H/E;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA6C3E;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA8B/E;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA8Q3E;AA8xBD;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA2R3E;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA2L/E;AAsBD;;GAEG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAoB1E;AAgBD;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAmE7E;AAiCD;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAM9E;AAkBD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA8D/E"}
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { lexiconNames } from "../../lexicon-module.js";
|
|
2
|
-
import { resolve } from "node:path";
|
|
2
|
+
import { basename, resolve } from "node:path";
|
|
3
3
|
import { commandBuildParams } from "../build-params-cli.js";
|
|
4
4
|
import { build } from "../../build.js";
|
|
5
5
|
import { takeSnapshot } from "../../lifecycle/snapshot.js";
|
|
6
|
-
import {
|
|
6
|
+
import { snapshotStorageKey, StaleLifecycleBranchError } from "../../lifecycle/git.js";
|
|
7
|
+
import { readEnvironmentSnapshotsFrom, resolveSnapshotStore } from "../../lifecycle/snapshot-store.js";
|
|
7
8
|
import { deepDiffForLexicon } from "../../lifecycle/deep-observe.js";
|
|
8
9
|
import { countUnclaimed, countPending, countPropertyDrift, countHeld, suspiciousHeld } from "../../lifecycle/deep-diff.js";
|
|
9
10
|
import { describePathOrigin, getPathProvenance, getProvenance } from "../../provenance.js";
|
|
10
11
|
import { resolveDeepDrift, resolveDriftedField } from "../../fold-provenance.js";
|
|
11
|
-
import { acceptDeviations, baselineForLexicon, emptyBaseline, readObservationBaseline,
|
|
12
|
+
import { acceptDeviations, baselineForLexicon, emptyBaseline, readObservationBaseline, saveObservationBaseline, } from "../../lifecycle/observation-baseline.js";
|
|
12
13
|
import { computeBuildDigest, declaredDefinitions, diffDigests } from "../../lifecycle/digest.js";
|
|
14
|
+
import { diffDeclaredAgainstIndex, indexDriftDocument } from "../../lifecycle/index-drift.js";
|
|
15
|
+
import { joinCell, parseIndexRef, readIndexRef } from "../../lifecycle/index-join.js";
|
|
16
|
+
import { CHANT_VERSION } from "../../chant-version.js";
|
|
13
17
|
import { diffLive, diffLiveArtifacts, diffSnapshots, missingRow } from "../../lifecycle/live-diff.js";
|
|
14
18
|
import { buildChangeSet, renderChangeSet, renderChangeSetMarkdown, gitlabMrReport, unobservedPlanNotice } from "../../lifecycle/change-set.js";
|
|
15
19
|
import { mergeReceiptEntries, observedValueResolver, planReceipts, readReceiptValue } from "../../lifecycle/receipt-plan.js";
|
|
@@ -100,6 +104,7 @@ export async function runLifecycleSnapshot(ctx) {
|
|
|
100
104
|
// from its own scoped root — so its logical ids match what it deploys — and
|
|
101
105
|
// snapshots against its own live stack name (#932).
|
|
102
106
|
const targets = resolveStackTargets(args, config);
|
|
107
|
+
const store = await resolveSnapshotStore({ cwd: projectPath, config });
|
|
103
108
|
let anySnapshotSaved = false;
|
|
104
109
|
let anyHardError = false;
|
|
105
110
|
// #1166 — same self-sufficiency as `chant graph --live`: a snapshot is
|
|
@@ -139,6 +144,7 @@ export async function runLifecycleSnapshot(ctx) {
|
|
|
139
144
|
deep: args.deep,
|
|
140
145
|
ambient: args.ambient,
|
|
141
146
|
ambientKinds: projectKinds,
|
|
147
|
+
store,
|
|
142
148
|
});
|
|
143
149
|
}
|
|
144
150
|
catch (err) {
|
|
@@ -163,7 +169,10 @@ export async function runLifecycleSnapshot(ctx) {
|
|
|
163
169
|
const counts = result.snapshots
|
|
164
170
|
.map((s) => `${s.lexicon}(${Object.keys(s.resources).length})`)
|
|
165
171
|
.join(" ");
|
|
166
|
-
|
|
172
|
+
// `none` keeps nothing, and says so: the observation still ran (#4519).
|
|
173
|
+
console.error(result.store && !result.store.written
|
|
174
|
+
? formatWarning({ message: `${prefix}Snapshot observed, not kept: the store is ${result.store.where} (${counts})` })
|
|
175
|
+
: formatSuccess(`${prefix}Snapshot saved to ${store.where} (${counts})`));
|
|
167
176
|
}
|
|
168
177
|
if (result.errors.length > 0)
|
|
169
178
|
anyHardError = true;
|
|
@@ -185,9 +194,10 @@ export async function runLifecycleShow(ctx) {
|
|
|
185
194
|
return 1;
|
|
186
195
|
}
|
|
187
196
|
// Fetch from remote first
|
|
188
|
-
await
|
|
197
|
+
const store = await resolveSnapshotStore();
|
|
198
|
+
await store.fetch();
|
|
189
199
|
if (lexiconFilter) {
|
|
190
|
-
const content = await
|
|
200
|
+
const content = await store.readLatest(environment, lexiconFilter);
|
|
191
201
|
if (!content) {
|
|
192
202
|
console.error(formatError({ message: `No snapshot found for ${environment}/${lexiconFilter}` }));
|
|
193
203
|
return 1;
|
|
@@ -196,7 +206,7 @@ export async function runLifecycleShow(ctx) {
|
|
|
196
206
|
printSnapshotTable(snapshot);
|
|
197
207
|
}
|
|
198
208
|
else {
|
|
199
|
-
const snapshots = await
|
|
209
|
+
const snapshots = await readEnvironmentSnapshotsFrom(store, environment);
|
|
200
210
|
if (snapshots.size === 0) {
|
|
201
211
|
console.error(formatError({ message: `No snapshots found for environment "${environment}"` }));
|
|
202
212
|
return 1;
|
|
@@ -277,6 +287,21 @@ export async function runLifecycleDiff(ctx) {
|
|
|
277
287
|
json: !!args.json,
|
|
278
288
|
});
|
|
279
289
|
}
|
|
290
|
+
// `--index <ref>` (#4526): the observed side is an index version in the
|
|
291
|
+
// store, not a live read and not a snapshot.
|
|
292
|
+
const indexMode = args.index !== undefined;
|
|
293
|
+
if (indexMode && (args.live || (args.betweenA && args.betweenB))) {
|
|
294
|
+
console.error(formatError({
|
|
295
|
+
message: `chant lifecycle diff takes --index or ${args.live ? "--live" : "--between"}, not both`,
|
|
296
|
+
hint: "--index compares source with an index version in the store; --live reads the estate now; --between compares two snapshots",
|
|
297
|
+
}));
|
|
298
|
+
return 1;
|
|
299
|
+
}
|
|
300
|
+
const indexRef = indexMode ? parseIndexRef(String(args.index)) : undefined;
|
|
301
|
+
if (indexRef && "error" in indexRef) {
|
|
302
|
+
console.error(formatError({ message: indexRef.error, hint: indexRef.hint }));
|
|
303
|
+
return 1;
|
|
304
|
+
}
|
|
280
305
|
// Filter serializers to target lexicon before building
|
|
281
306
|
const targetSerializers = lexiconFilter
|
|
282
307
|
? plugins.filter((p) => p.name === lexiconFilter).map((p) => p.serializer)
|
|
@@ -288,7 +313,18 @@ export async function runLifecycleDiff(ctx) {
|
|
|
288
313
|
const declaredParams = await commandBuildParams(config.buildParams, args);
|
|
289
314
|
if (!declaredParams)
|
|
290
315
|
return 1;
|
|
291
|
-
await
|
|
316
|
+
const store = await resolveSnapshotStore({ config });
|
|
317
|
+
await store.fetch();
|
|
318
|
+
let indexRead;
|
|
319
|
+
if (indexRef && !("error" in indexRef)) {
|
|
320
|
+
const read = await readIndexRef(store, indexRef);
|
|
321
|
+
if ("error" in read) {
|
|
322
|
+
console.error(formatError({ message: read.error, ...(read.hint ? { hint: read.hint } : {}) }));
|
|
323
|
+
return 1;
|
|
324
|
+
}
|
|
325
|
+
indexRead = read;
|
|
326
|
+
}
|
|
327
|
+
const indexResults = [];
|
|
292
328
|
// One target per stack (single-stack projects: exactly one), each built from
|
|
293
329
|
// its own scoped root and diffed against its own live stack name (#932).
|
|
294
330
|
const targets = resolveStackTargets(args, config);
|
|
@@ -302,7 +338,7 @@ export async function runLifecycleDiff(ctx) {
|
|
|
302
338
|
// Accepted-deviation baseline (#1014). Read once for the whole run — it is
|
|
303
339
|
// env-keyed, not stack-keyed, and every deep pass subtracts from the same
|
|
304
340
|
// committed set. Absent is the normal state (nothing accepted yet).
|
|
305
|
-
const baseline = args.live ? await readObservationBaseline(environment) : null;
|
|
341
|
+
const baseline = args.live || indexRead ? await readObservationBaseline(environment, { config }) : null;
|
|
306
342
|
const accepted = {};
|
|
307
343
|
// Effect receipts across every target's build (#1833) — `--update-baseline`
|
|
308
344
|
// refuses to accept drift on them (the effect step is their only writer),
|
|
@@ -312,7 +348,7 @@ export async function runLifecycleDiff(ctx) {
|
|
|
312
348
|
// Floci), so `--live` is self-sufficient even when the ambient shell never
|
|
313
349
|
// exported e.g. AWS_ENDPOINT_URL. Ambient always wins when it's already set.
|
|
314
350
|
// Scoped to just the live reads below — restored in `finally`.
|
|
315
|
-
const liveLexicons = args.live ? plugins.filter((p) => p.describeResources || p.listArtifacts) : [];
|
|
351
|
+
const liveLexicons = args.live && !indexRead ? plugins.filter((p) => p.describeResources || p.listArtifacts) : [];
|
|
316
352
|
const endpointResult = applyLiveEndpoint(config.environments, environment, liveLexicons);
|
|
317
353
|
if (endpointResult.notice)
|
|
318
354
|
console.error(formatWarning({ message: endpointResult.notice }));
|
|
@@ -377,6 +413,7 @@ export async function runLifecycleDiff(ctx) {
|
|
|
377
413
|
plugins,
|
|
378
414
|
buildResult,
|
|
379
415
|
json,
|
|
416
|
+
store,
|
|
380
417
|
stack: target.stack,
|
|
381
418
|
region: target.region,
|
|
382
419
|
componentStacks,
|
|
@@ -402,15 +439,69 @@ export async function runLifecycleDiff(ctx) {
|
|
|
402
439
|
combinedLexiconsJson = r.byLexicon;
|
|
403
440
|
}
|
|
404
441
|
}
|
|
442
|
+
else if (indexRead) {
|
|
443
|
+
const r = runLifecycleDiffIndex({
|
|
444
|
+
read: indexRead,
|
|
445
|
+
lexicons: lexiconFilter ? [lexiconFilter] : builtLexicons,
|
|
446
|
+
plugins,
|
|
447
|
+
buildResult,
|
|
448
|
+
baseline,
|
|
449
|
+
member: basename(projectRoot),
|
|
450
|
+
stack: target.stack,
|
|
451
|
+
region: target.region,
|
|
452
|
+
json,
|
|
453
|
+
projectRoot,
|
|
454
|
+
});
|
|
455
|
+
indexResults.push(r);
|
|
456
|
+
for (const [lexicon, part] of Object.entries(r.byLexicon)) {
|
|
457
|
+
if (args.updateBaseline)
|
|
458
|
+
(accepted[lexicon] ?? (accepted[lexicon] = [])).push(...deviationsToAccept(part.deep));
|
|
459
|
+
}
|
|
460
|
+
if (args.updateBaseline) {
|
|
461
|
+
for (const name of collectEffectReceipts(buildResult.entities).keys())
|
|
462
|
+
receiptEntities.add(name);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
405
465
|
else {
|
|
406
|
-
await runLifecycleDiffDigest({ environment, lexicons, buildResult, stack: target.stack });
|
|
466
|
+
await runLifecycleDiffDigest({ environment, lexicons, buildResult, stack: target.stack, store });
|
|
407
467
|
}
|
|
408
468
|
}
|
|
409
469
|
// `--update-baseline` (#1014): record what the deep pass just reported as
|
|
410
470
|
// accepted, so it stops re-alerting. Runs before the summary lines so the
|
|
411
471
|
// "no drift" verdict below still describes the run that produced it.
|
|
412
|
-
if (args.live && args.updateBaseline) {
|
|
413
|
-
await recordAcceptedBaseline(environment, baseline, accepted, json, receiptEntities);
|
|
472
|
+
if ((args.live || indexRead) && args.updateBaseline) {
|
|
473
|
+
await recordAcceptedBaseline(environment, baseline, accepted, json, receiptEntities, config);
|
|
474
|
+
}
|
|
475
|
+
if (indexRead) {
|
|
476
|
+
// Drift records, drift document v1 (#4526).
|
|
477
|
+
if (json)
|
|
478
|
+
console.log(JSON.stringify(indexDriftDocument(indexResults, CHANT_VERSION)));
|
|
479
|
+
else {
|
|
480
|
+
const sum = (k) => indexResults.reduce((n, r) => n + r.counts[k], 0);
|
|
481
|
+
const ref = indexResults[0]?.ref;
|
|
482
|
+
const declaredCount = sum("declared");
|
|
483
|
+
const drift = sum("properties") + sum("pending");
|
|
484
|
+
const notObserved = sum("notObserved");
|
|
485
|
+
if (anyBuildError) {
|
|
486
|
+
// the build error is already printed
|
|
487
|
+
}
|
|
488
|
+
else if (declaredCount === 0) {
|
|
489
|
+
console.error(formatWarning({ message: "No declared entities to compare with the index" }));
|
|
490
|
+
}
|
|
491
|
+
else if (drift === 0) {
|
|
492
|
+
console.error(notObserved > 0
|
|
493
|
+
? formatWarning({
|
|
494
|
+
message: `No drift detected against index ${ref} across ${sum("bound")} bound entity(ies), but ${notObserved} declared entity(ies) are not observed by it: that part of the estate is unknown, not clean`,
|
|
495
|
+
})
|
|
496
|
+
: formatSuccess(`No drift detected against index ${ref} across ${declaredCount} declared entity(ies)`));
|
|
497
|
+
}
|
|
498
|
+
else {
|
|
499
|
+
console.error(formatWarning({
|
|
500
|
+
message: `Drift against index ${ref}: ${sum("properties")} property difference(s) on ${sum("drifted")} entity(ies), ${sum("pending")} declared entity(ies) absent from it, ${notObserved} not observed`,
|
|
501
|
+
}));
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
return anyBuildError ? 1 : 0;
|
|
414
505
|
}
|
|
415
506
|
if (args.live) {
|
|
416
507
|
if (json) {
|
|
@@ -451,7 +542,7 @@ export async function runLifecycleDiff(ctx) {
|
|
|
451
542
|
* count and the storage path, and a failed push says so rather than leaving
|
|
452
543
|
* the operator believing the team's baseline moved.
|
|
453
544
|
*/
|
|
454
|
-
async function recordAcceptedBaseline(environment, existing, accepted, json, receipts) {
|
|
545
|
+
async function recordAcceptedBaseline(environment, existing, accepted, json, receipts, config) {
|
|
455
546
|
const total = Object.values(accepted).reduce((n, d) => n + d.length, 0);
|
|
456
547
|
if (total === 0) {
|
|
457
548
|
if (!json) {
|
|
@@ -469,11 +560,15 @@ async function recordAcceptedBaseline(environment, existing, accepted, json, rec
|
|
|
469
560
|
for (const [lexicon, deviations] of Object.entries(accepted)) {
|
|
470
561
|
next = acceptDeviations(next, lexicon, deviations, { receipts });
|
|
471
562
|
}
|
|
472
|
-
|
|
473
|
-
|
|
563
|
+
// A file under .chant/observation-baseline/ by default (#4519): commit it
|
|
564
|
+
// with the change that needed it, so the acceptance is reviewed.
|
|
565
|
+
const saved = await saveObservationBaseline(next, config ? { config } : undefined);
|
|
474
566
|
if (!json) {
|
|
475
|
-
|
|
476
|
-
|
|
567
|
+
const note = saved.published === "pushed" ? " (pushed)"
|
|
568
|
+
: saved.published === "file" ? " (commit it to keep it)"
|
|
569
|
+
: saved.published === "none" ? " (the baseline store is none: nothing kept)"
|
|
570
|
+
: " (local only — no remote configured or push refused)";
|
|
571
|
+
console.error(formatSuccess(`--update-baseline: accepted ${total} deviation(s) into ${saved.where}${note}`));
|
|
477
572
|
}
|
|
478
573
|
}
|
|
479
574
|
catch (err) {
|
|
@@ -489,8 +584,9 @@ async function recordAcceptedBaseline(environment, existing, accepted, json, rec
|
|
|
489
584
|
* two-way delta per lexicon.
|
|
490
585
|
*/
|
|
491
586
|
async function runLifecycleDiffBetween(args) {
|
|
492
|
-
await fetchLifecycle();
|
|
493
587
|
const { config } = await loadChantConfig(resolve("."));
|
|
588
|
+
const store = await resolveSnapshotStore({ config });
|
|
589
|
+
await store.fetch();
|
|
494
590
|
const lexicons = args.lexiconFilter ? [args.lexiconFilter] : lexiconNames(config.lexicons ?? []);
|
|
495
591
|
if (lexicons.length === 0) {
|
|
496
592
|
console.error(formatError({ message: "No lexicons to diff — pass a lexicon or declare `lexicons` in chant.config." }));
|
|
@@ -508,8 +604,8 @@ async function runLifecycleDiffBetween(args) {
|
|
|
508
604
|
};
|
|
509
605
|
const byLexicon = {};
|
|
510
606
|
for (const lexicon of lexicons) {
|
|
511
|
-
const prev = parseResources(await
|
|
512
|
-
const next = parseResources(await
|
|
607
|
+
const prev = parseResources(await store.readAt(args.environment, lexicon, args.refA));
|
|
608
|
+
const next = parseResources(await store.readAt(args.environment, lexicon, args.refB));
|
|
513
609
|
if (prev === null && next === null) {
|
|
514
610
|
if (!args.json)
|
|
515
611
|
console.error(formatWarning({ message: `${lexicon}: not captured at either ref — skipping` }));
|
|
@@ -542,7 +638,7 @@ async function runLifecycleDiffDigest(args) {
|
|
|
542
638
|
if (args.stack)
|
|
543
639
|
console.log(`\n${formatBold(`■ stack ${args.stack}`)}`);
|
|
544
640
|
for (const lexicon of args.lexicons) {
|
|
545
|
-
const content = await
|
|
641
|
+
const content = await args.store.readLatest(args.environment, snapshotStorageKey(lexicon, args.stack));
|
|
546
642
|
let previousDigest = undefined;
|
|
547
643
|
if (content) {
|
|
548
644
|
const snapshot = JSON.parse(content);
|
|
@@ -672,7 +768,7 @@ async function runLifecycleDiffLive(args) {
|
|
|
672
768
|
: rawOutput.primary;
|
|
673
769
|
// Read previous snapshot once; both flows pull what they need.
|
|
674
770
|
let prevSnapshot;
|
|
675
|
-
const content = await
|
|
771
|
+
const content = await args.store.readLatest(args.environment, snapshotStorageKey(lexiconName, args.stack));
|
|
676
772
|
if (content)
|
|
677
773
|
prevSnapshot = JSON.parse(content);
|
|
678
774
|
let lexiconChecked = false;
|
|
@@ -790,6 +886,65 @@ async function runLifecycleDiffLive(args) {
|
|
|
790
886
|
}
|
|
791
887
|
return { byLexicon, totalDrift, totalUnobserved, totalLexiconsChecked, toAccept };
|
|
792
888
|
}
|
|
889
|
+
/**
|
|
890
|
+
* `chant lifecycle diff <env> --index <ref>` for one stack (#4526): every
|
|
891
|
+
* declared entity joined to the index version, the bound ones deep-diffed
|
|
892
|
+
* against their indexed trees, the rest reported with their join verdict.
|
|
893
|
+
* Reads nothing but the store. See ../../lifecycle/index-drift.ts.
|
|
894
|
+
*/
|
|
895
|
+
function runLifecycleDiffIndex(args) {
|
|
896
|
+
const entities = new Map();
|
|
897
|
+
for (const lexicon of args.lexicons)
|
|
898
|
+
entities.set(lexicon, new Map());
|
|
899
|
+
for (const [name, entity] of args.buildResult.entities) {
|
|
900
|
+
const forLexicon = entities.get(entity.lexicon);
|
|
901
|
+
if (!forLexicon || !isObservableDeclarable(entity))
|
|
902
|
+
continue;
|
|
903
|
+
const pathOrigins = getPathProvenance(entity);
|
|
904
|
+
forLexicon.set(name, {
|
|
905
|
+
entityType: entity.entityType,
|
|
906
|
+
props: (entity.props != null ? entity.props : {}),
|
|
907
|
+
...(pathOrigins ? { pathOrigins } : {}),
|
|
908
|
+
});
|
|
909
|
+
}
|
|
910
|
+
const result = diffDeclaredAgainstIndex({
|
|
911
|
+
doc: args.read.doc,
|
|
912
|
+
version: args.read.version,
|
|
913
|
+
entities,
|
|
914
|
+
lexicons: args.plugins,
|
|
915
|
+
baseline: args.baseline,
|
|
916
|
+
member: args.member,
|
|
917
|
+
...(args.stack ? { stack: args.stack } : {}),
|
|
918
|
+
...(args.region ? { region: args.region } : {}),
|
|
919
|
+
chant: CHANT_VERSION,
|
|
920
|
+
});
|
|
921
|
+
if (args.json)
|
|
922
|
+
return result;
|
|
923
|
+
const { stamp } = args.read.doc;
|
|
924
|
+
const by = stamp.source.version ? `${stamp.source.name} ${stamp.source.version}` : stamp.source.name;
|
|
925
|
+
if (args.stack)
|
|
926
|
+
console.log(`\n${formatBold(`■ stack ${args.stack}`)}`);
|
|
927
|
+
console.log(`index ${result.ref}, read ${stamp.observedAt} by ${by}`);
|
|
928
|
+
const provenanceOf = (name) => {
|
|
929
|
+
const entity = args.buildResult.entities.get(name);
|
|
930
|
+
return entity ? getProvenance(entity) : undefined;
|
|
931
|
+
};
|
|
932
|
+
for (const [lexicon, part] of Object.entries(result.byLexicon)) {
|
|
933
|
+
const rows = Object.entries(part.joins).sort(([a], [b]) => a.localeCompare(b));
|
|
934
|
+
const bound = rows.filter(([, j]) => j.verdict === "bound").length;
|
|
935
|
+
console.log(formatBold(`\n${lexicon}: ${bound}/${rows.length} declared entity(ies) bound to the index`));
|
|
936
|
+
const unbound = rows.filter(([, j]) => j.verdict !== "bound");
|
|
937
|
+
if (unbound.length > 0) {
|
|
938
|
+
console.log(formatBold("\nNOT COMPARED (the join did not bind; never diffed):"));
|
|
939
|
+
for (const [name, j] of unbound) {
|
|
940
|
+
const detail = "detail" in j ? `: ${j.detail}` : j.verdict === "absent" ? ": the index listed its type and location and does not hold it" : "";
|
|
941
|
+
console.log(` ? ${name} ${joinCell(j) ?? ""}${detail}`);
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
renderDeepDiff(lexicon, part.deep, provenanceOf, args.projectRoot);
|
|
945
|
+
}
|
|
946
|
+
return result;
|
|
947
|
+
}
|
|
793
948
|
/**
|
|
794
949
|
* Everything a deep diff reported this run, as deviations to record accepted.
|
|
795
950
|
* `--update-baseline` accepts what was *reported*, never what was already
|
|
@@ -1068,7 +1223,8 @@ export async function runLifecyclePlan(ctx) {
|
|
|
1068
1223
|
console.error(formatError({ message: "Build failed — fix errors before planning" }));
|
|
1069
1224
|
return 1;
|
|
1070
1225
|
}
|
|
1071
|
-
await
|
|
1226
|
+
const store = await resolveSnapshotStore({ config });
|
|
1227
|
+
await store.fetch();
|
|
1072
1228
|
const lexicons = lexiconFilter ? [lexiconFilter] : Array.from(buildResult.manifest.lexicons);
|
|
1073
1229
|
// Multi-stack component projects deploy one CFN stack per component, so the
|
|
1074
1230
|
// single-stack-per-env observe below would see nothing live and plan every
|
|
@@ -1219,7 +1375,8 @@ export async function runLifecyclePlan(ctx) {
|
|
|
1219
1375
|
receiptReadings.set(receiptName, { observed: true, present: false, lexicon: lexiconName });
|
|
1220
1376
|
}
|
|
1221
1377
|
}
|
|
1222
|
-
|
|
1378
|
+
// Evidence only (#4519): the change set never makes a decision from it.
|
|
1379
|
+
const content = await store.readLatest(environment, lexiconName);
|
|
1223
1380
|
const observedThen = content ? JSON.parse(content).resources : undefined;
|
|
1224
1381
|
const cs = buildChangeSet(environment, {
|
|
1225
1382
|
declared,
|
|
@@ -1500,15 +1657,18 @@ async function promptProdTeardown(environment) {
|
|
|
1500
1657
|
*/
|
|
1501
1658
|
export async function runLifecycleLog(ctx) {
|
|
1502
1659
|
const environment = ctx.args.extraPositional;
|
|
1503
|
-
await
|
|
1504
|
-
|
|
1660
|
+
const store = await resolveSnapshotStore();
|
|
1661
|
+
await store.fetch();
|
|
1662
|
+
const entries = await store.list({ ...(environment ? { environment } : {}) });
|
|
1505
1663
|
if (entries.length === 0) {
|
|
1506
1664
|
console.error(formatError({ message: "No state snapshots found" }));
|
|
1507
1665
|
return 1;
|
|
1508
1666
|
}
|
|
1667
|
+
// A git store's version is a commit; s3's an object version, local's a time.
|
|
1668
|
+
const isCommit = (v) => /^[0-9a-f]{40}$/.test(v);
|
|
1509
1669
|
for (const entry of entries) {
|
|
1510
1670
|
const date = entry.date.split("T")[0];
|
|
1511
|
-
console.log(`${entry.
|
|
1671
|
+
console.log(`${isCommit(entry.version) ? entry.version.slice(0, 7) : entry.version} ${date} ${entry.key ?? entry.message}`);
|
|
1512
1672
|
}
|
|
1513
1673
|
return 0;
|
|
1514
1674
|
}
|
|
@@ -1,7 +1,16 @@
|
|
|
1
|
+
import type { IndexImportSelection } from "../../lifecycle/index-import.js";
|
|
1
2
|
import type { CommandContext } from "../registry.js";
|
|
2
3
|
export declare function runAudit(ctx: CommandContext): Promise<number>;
|
|
3
4
|
export declare function runList(ctx: CommandContext): Promise<number>;
|
|
4
5
|
export declare function runDescribe(ctx: CommandContext): Promise<number>;
|
|
6
|
+
/**
|
|
7
|
+
* The selection for `chant import --index` (#4524). `--type` and `--name`
|
|
8
|
+
* take comma-separated lists, `--tag key=value` repeats, `--select` is a JSON
|
|
9
|
+
* file of node ids (a list of ids, of `{ id }` or `{ node }` objects, or an
|
|
10
|
+
* object holding `nodes` or `results`) or a comma-separated list of ids, and
|
|
11
|
+
* `--all` takes every node.
|
|
12
|
+
*/
|
|
13
|
+
export declare function indexSelectionFromArgs(args: CommandContext["args"]): IndexImportSelection | Error;
|
|
5
14
|
export declare function runImport(ctx: CommandContext): Promise<number>;
|
|
6
15
|
export declare function runUpdate(ctx: CommandContext): Promise<number>;
|
|
7
16
|
export declare function runDoctor(ctx: CommandContext): Promise<number>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"misc.d.ts","sourceRoot":"","sources":["../../../src/cli/handlers/misc.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"misc.d.ts","sourceRoot":"","sources":["../../../src/cli/handlers/misc.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAQzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AA8ClD,wBAAsB,QAAQ,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAqGnE;AAED,wBAAsB,OAAO,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAuClE;AAED,wBAAsB,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA8CtE;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,GAAG,oBAAoB,GAAG,KAAK,CAwCjG;AAED,wBAAsB,SAAS,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA2KpE;AAED,wBAAsB,SAAS,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAKpE;AAED,wBAAsB,SAAS,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBpE"}
|