@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
package/src/graph-ir.ts
CHANGED
|
@@ -7,7 +7,9 @@ import { getProvenance } from "./provenance";
|
|
|
7
7
|
import { INTRINSIC_MARKER } from "./intrinsic";
|
|
8
8
|
import { subTemplateRefs } from "./graph-sub-template";
|
|
9
9
|
import type { ResourceMetadata } from "./lexicon";
|
|
10
|
-
import type
|
|
10
|
+
import { entityInstanceRollup, observedInstanceNodeId, type InstanceRollup } from "./instance-nodes";
|
|
11
|
+
import type { RootRead, UnobservedEntity } from "./observation";
|
|
12
|
+
import type { EdgeGrain, EngineFacts } from "./engine-facts";
|
|
11
13
|
|
|
12
14
|
export { subTemplateRefs };
|
|
13
15
|
|
|
@@ -95,6 +97,68 @@ export interface IRNode {
|
|
|
95
97
|
* unaffected.
|
|
96
98
|
*/
|
|
97
99
|
runtimeOwner?: string;
|
|
100
|
+
/**
|
|
101
|
+
* On an instance node of a `count` or `for_each` block (#4454): the block
|
|
102
|
+
* node's id. The node's own id is that id followed by {@link instanceKey},
|
|
103
|
+
* `aws_eip.pool[0]` under `aws_eip.pool`, and the block node stays in the
|
|
104
|
+
* graph as the rollup. Absent on every other node. See `./instance-nodes.ts`.
|
|
105
|
+
*/
|
|
106
|
+
instanceOf?: string;
|
|
107
|
+
/**
|
|
108
|
+
* With {@link instanceOf}: the block's own instance key as the engine
|
|
109
|
+
* prints it, `[0]` or `["a"]`. Absent on an instance that only an
|
|
110
|
+
* expanded enclosing scope makes (#4486), a block without `count` under
|
|
111
|
+
* `module "app" { count = 2 }`.
|
|
112
|
+
*/
|
|
113
|
+
instanceKey?: string;
|
|
114
|
+
/**
|
|
115
|
+
* With {@link instanceOf}, under an expanded enclosing scope (#4486): that
|
|
116
|
+
* scope's path as the engine prints it, `module.app[0]`. The node id then
|
|
117
|
+
* carries the key on the scope's segment, `estate/module.app[0]/aws_eip.pool[1]`.
|
|
118
|
+
*/
|
|
119
|
+
instanceScope?: string;
|
|
120
|
+
/**
|
|
121
|
+
* On a block node whose `count` or `for_each` the declared graph cannot
|
|
122
|
+
* count (#4489): why it stays one node, and the expression. Absent on a
|
|
123
|
+
* block that is not expanded and on one whose instances are listed. See
|
|
124
|
+
* `./instance-nodes.ts`.
|
|
125
|
+
*/
|
|
126
|
+
instanceRollup?: InstanceRollup;
|
|
127
|
+
/**
|
|
128
|
+
* What an ownership engine (choudoufu, plunge) observed about this node
|
|
129
|
+
* (#4520, #4527). On a live node it is copied from `ResourceMetadata.facts`.
|
|
130
|
+
* On a declared node it comes from the entity's {@link entityFacts}: the
|
|
131
|
+
* pulumi lexicon reads a plunge member's checked-in `engine-graph.json`
|
|
132
|
+
* beside its stack export (#4529). For people and for readers that show
|
|
133
|
+
* the graph. Nothing in chant decides from it, and {@link ownership} keeps
|
|
134
|
+
* its own meaning. Absent unless an engine supplied it. See `./engine-facts.ts`.
|
|
135
|
+
*/
|
|
136
|
+
facts?: EngineFacts;
|
|
137
|
+
/**
|
|
138
|
+
* Indexed nodes only (#4521, behold#1025): the inventory API's own type
|
|
139
|
+
* name, as the cloud lister read it: `AWS::S3::Bucket`,
|
|
140
|
+
* `microsoft.storage/storageaccounts`, `storage.googleapis.com/Bucket`,
|
|
141
|
+
* `apps/v1/Deployment`. Absent on every node a cloud listing did not make.
|
|
142
|
+
*/
|
|
143
|
+
listedType?: string;
|
|
144
|
+
/**
|
|
145
|
+
* Indexed nodes only: the region or location the object was listed in,
|
|
146
|
+
* `global` for a global type, a namespace or `cluster` for Kubernetes.
|
|
147
|
+
*/
|
|
148
|
+
location?: string;
|
|
149
|
+
/**
|
|
150
|
+
* Indexed nodes only: the identifier the listing returned, Cloud Control's
|
|
151
|
+
* `Identifier`, the ARM id, the asset `name`, or `namespace/name`.
|
|
152
|
+
*/
|
|
153
|
+
nativeId?: string;
|
|
154
|
+
/** Indexed nodes only: tags or labels as read, masked by key. Where markers come from. */
|
|
155
|
+
tags?: Record<string, string>;
|
|
156
|
+
/**
|
|
157
|
+
* Indexed nodes only: true when no lexicon kind maps the listed type. The
|
|
158
|
+
* node keeps `kind` = {@link listedType} and `lexicon` = the substrate, and
|
|
159
|
+
* is never dropped (#4521).
|
|
160
|
+
*/
|
|
161
|
+
unmappedKind?: boolean;
|
|
98
162
|
}
|
|
99
163
|
|
|
100
164
|
/**
|
|
@@ -134,6 +198,34 @@ export interface IREdge {
|
|
|
134
198
|
* this to route the edge between groups. Absent on every in-pipeline edge.
|
|
135
199
|
*/
|
|
136
200
|
crossPipeline?: boolean;
|
|
201
|
+
/**
|
|
202
|
+
* What the edge joins (#4520): two blocks, two instances, or a property of
|
|
203
|
+
* one instance to another. Set by an engine's graph (choudoufu: `block`;
|
|
204
|
+
* plunge: `instance` for dependencies, parents and providers, `property`
|
|
205
|
+
* for property dependencies). Absent when the source does not say. Two
|
|
206
|
+
* edges between the same pair that differ only in grain are two edges.
|
|
207
|
+
*/
|
|
208
|
+
grain?: EdgeGrain;
|
|
209
|
+
/**
|
|
210
|
+
* Where the edge came from (behold#1025): `declared` (an AttrRef or an
|
|
211
|
+
* EntityReference), `observed` (the engine or the cloud reported it), or
|
|
212
|
+
* `derived` (a reference catalog rule matched an attribute value to another
|
|
213
|
+
* node, #4522). Absent reads as `declared` on a source IR and `observed` on
|
|
214
|
+
* a live one, which is what both meant before the field.
|
|
215
|
+
*/
|
|
216
|
+
origin?: "declared" | "observed" | "derived";
|
|
217
|
+
/**
|
|
218
|
+
* With `origin: "derived"`: the rule that produced the edge,
|
|
219
|
+
* `<lexicon>:<from kind>:<path>` for a catalog rule and
|
|
220
|
+
* `<lexicon>:<from kind>:tag:<key>` for a typed tag rule.
|
|
221
|
+
*/
|
|
222
|
+
rule?: string;
|
|
223
|
+
/**
|
|
224
|
+
* `reference` (the default when absent) or `containment`: the holder sits
|
|
225
|
+
* inside the target (a subnet in its VPC). A containment edge is also in
|
|
226
|
+
* `groups.byContainer`, so a renderer that draws boxes can skip the line.
|
|
227
|
+
*/
|
|
228
|
+
relation?: "reference" | "containment";
|
|
137
229
|
}
|
|
138
230
|
|
|
139
231
|
/**
|
|
@@ -286,6 +378,8 @@ export interface EntityReference {
|
|
|
286
378
|
viaAttr?: string;
|
|
287
379
|
/** The producer-side attribute referenced (`IREdge.toAttr`), when the reference named exactly one. */
|
|
288
380
|
toAttr?: string;
|
|
381
|
+
/** What the reference joins (`IREdge.grain`, #4529), when its source says. */
|
|
382
|
+
grain?: EdgeGrain;
|
|
289
383
|
}
|
|
290
384
|
|
|
291
385
|
/** True when `value` has the {@link EntityReference} shape. */
|
|
@@ -329,6 +423,59 @@ export function entityStack(entity: Declarable): string | undefined {
|
|
|
329
423
|
return typeof stack === "string" && stack.length > 0 ? stack : undefined;
|
|
330
424
|
}
|
|
331
425
|
|
|
426
|
+
/**
|
|
427
|
+
* What an ownership engine observed about an entity (#4529), or undefined.
|
|
428
|
+
* Duck-typed like {@link entityStack}: the pulumi lexicon sets `facts` on a
|
|
429
|
+
* plunge member's entity from the member's checked-in engine graph. It is
|
|
430
|
+
* defined non-enumerable there, so a chant older than this reader does not
|
|
431
|
+
* project it into `attrs`. {@link buildGraphIr} copies it onto the node, and
|
|
432
|
+
* nothing in chant decides from it (see `IRNode.facts`).
|
|
433
|
+
*/
|
|
434
|
+
export function entityFacts(entity: Declarable): EngineFacts | undefined {
|
|
435
|
+
const facts = (entity as unknown as { facts?: unknown }).facts;
|
|
436
|
+
return typeof facts === "object" && facts !== null && !Array.isArray(facts) ? (facts as EngineFacts) : undefined;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* The instance keys an entity says its source expands to (#4454), as the
|
|
441
|
+
* engine prints them (`[0]`, `["a"]`), or an empty list. Duck-typed like
|
|
442
|
+
* {@link entityStack}: the terraform lexicon sets `instanceKeys` on a block
|
|
443
|
+
* whose `count` or `for_each` is a literal.
|
|
444
|
+
*/
|
|
445
|
+
export function entityInstanceKeys(entity: Declarable): readonly string[] {
|
|
446
|
+
const keys = (entity as unknown as { instanceKeys?: unknown }).instanceKeys;
|
|
447
|
+
if (!Array.isArray(keys)) return [];
|
|
448
|
+
return keys.filter((k): k is string => typeof k === "string" && k.startsWith("[") && k.endsWith("]"));
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/** One instance node an entity names (#4486): its full id, and the key and scope it carries. */
|
|
452
|
+
export interface EntityInstance {
|
|
453
|
+
id: string;
|
|
454
|
+
key?: string;
|
|
455
|
+
scope?: string;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* The instance nodes an entity names, given its own key `name`: the
|
|
460
|
+
* duck-typed `instances` list when it carries one (full ids, which an
|
|
461
|
+
* instance under an expanded module call needs, #4486), else one per
|
|
462
|
+
* {@link entityInstanceKeys} key, id `<name><key>`.
|
|
463
|
+
*/
|
|
464
|
+
export function entityInstances(name: string, entity: Declarable): EntityInstance[] {
|
|
465
|
+
const listed = (entity as unknown as { instances?: unknown }).instances;
|
|
466
|
+
if (Array.isArray(listed)) {
|
|
467
|
+
const out: EntityInstance[] = [];
|
|
468
|
+
for (const item of listed) {
|
|
469
|
+
if (typeof item !== "object" || item === null) continue;
|
|
470
|
+
const { id, key, scope } = item as { id?: unknown; key?: unknown; scope?: unknown };
|
|
471
|
+
if (typeof id !== "string" || id.length === 0 || id === name) continue;
|
|
472
|
+
out.push({ id, ...(typeof key === "string" ? { key } : {}), ...(typeof scope === "string" ? { scope } : {}) });
|
|
473
|
+
}
|
|
474
|
+
return out;
|
|
475
|
+
}
|
|
476
|
+
return entityInstanceKeys(entity).map((key) => ({ id: `${name}${key}`, key }));
|
|
477
|
+
}
|
|
478
|
+
|
|
332
479
|
/** Grouping metadata for cluster/subgraph rendering. Maps group name -> node ids. */
|
|
333
480
|
export interface IRGroups {
|
|
334
481
|
byLexicon?: Record<string, string[]>;
|
|
@@ -517,6 +664,18 @@ export interface GraphIR {
|
|
|
517
664
|
* (`capabilities/view.ts`). Absent unless asked for.
|
|
518
665
|
*/
|
|
519
666
|
capabilityView?: unknown;
|
|
667
|
+
/**
|
|
668
|
+
* With `chant graph --live` (INTENTIUS/chant#4452): which read answered each
|
|
669
|
+
* root, the observation's structured {@link RootRead} report passed through
|
|
670
|
+
* as the lexicon wrote it, keyed by the lexicon's root key (terraform uses
|
|
671
|
+
* `terraform.roots.<root>`). `depth` is the read asked for, and `fellBackTo`
|
|
672
|
+
* and `reason` are set only when that read failed, so the read that answered
|
|
673
|
+
* is `fellBackTo ?? depth`. A consumer reads this and never the stderr notes
|
|
674
|
+
* that say the same thing in prose. Additive: absent when no lexicon reported
|
|
675
|
+
* one (a lexicon with one read path, a source graph, an `--at` replay), and
|
|
676
|
+
* an older chant never writes it.
|
|
677
|
+
*/
|
|
678
|
+
rootReads?: Record<string, RootRead>;
|
|
520
679
|
}
|
|
521
680
|
|
|
522
681
|
/** A node is anything that serializes to a resource — not a property or output. */
|
|
@@ -730,7 +889,8 @@ function subEnvelope(sub: SubForm, seen: Set<unknown>, reverse: Map<object, stri
|
|
|
730
889
|
// entity's place in the graph, not declared configuration, and both are read
|
|
731
890
|
// directly, so projecting them into `attrs` would only restate an edge and a
|
|
732
891
|
// group key the IR already carries.
|
|
733
|
-
|
|
892
|
+
// `facts` (#4529) is an engine's observation, carried onto `IRNode.facts`, not configuration.
|
|
893
|
+
const SKIP_KEYS = new Set(["lexicon", "entityType", "kind", "attributes", "Ref", "references", "stack", "facts"]);
|
|
734
894
|
|
|
735
895
|
/** The config bag of a node, paired with each key. Lexicon entities keep their
|
|
736
896
|
* declared props in a (usually non-enumerable) `props` object; simpler entities
|
|
@@ -790,6 +950,7 @@ function collectEdges(
|
|
|
790
950
|
kind: "ref",
|
|
791
951
|
...(ref.viaAttr ? { viaAttr: ref.viaAttr } : {}),
|
|
792
952
|
...(ref.toAttr ? { toAttr: ref.toAttr } : {}),
|
|
953
|
+
...(ref.grain === "block" || ref.grain === "instance" || ref.grain === "property" ? { grain: ref.grain } : {}),
|
|
793
954
|
});
|
|
794
955
|
}
|
|
795
956
|
const seen = new Set<unknown>();
|
|
@@ -868,7 +1029,8 @@ function collectEdges(
|
|
|
868
1029
|
|
|
869
1030
|
/** Stable key for deduping and sorting an edge. */
|
|
870
1031
|
function edgeKey(e: IREdge): string {
|
|
871
|
-
|
|
1032
|
+
// `grain` joins the key only when set, so an edge without one keys as before.
|
|
1033
|
+
return `${e.from}\0${e.to}\0${e.viaAttr ?? ""}${e.grain ? `\0${e.grain}` : ""}`;
|
|
872
1034
|
}
|
|
873
1035
|
|
|
874
1036
|
/**
|
|
@@ -907,6 +1069,8 @@ export function buildGraphIr(
|
|
|
907
1069
|
if (prov?.compositeInstance) node.compositeInstance = prov.compositeInstance;
|
|
908
1070
|
const file = relFile(prov?.sourceFile, projectPath);
|
|
909
1071
|
if (file) node.sourceLoc = { file };
|
|
1072
|
+
const facts = entityFacts(entity);
|
|
1073
|
+
if (facts) node.facts = facts;
|
|
910
1074
|
nodes.push(node);
|
|
911
1075
|
|
|
912
1076
|
(byLexicon[entity.lexicon] ??= []).push(name);
|
|
@@ -982,6 +1146,71 @@ export function buildGraphIr(
|
|
|
982
1146
|
return ir;
|
|
983
1147
|
}
|
|
984
1148
|
|
|
1149
|
+
/**
|
|
1150
|
+
* Add an instance node (#4454) under each node whose entity names its
|
|
1151
|
+
* instances ({@link entityInstances}): id `<block id><key>`, or the full id
|
|
1152
|
+
* the entity lists under an expanded module call (#4486), the
|
|
1153
|
+
* block's kind, lexicon and source location, `instanceOf` and `instanceKey`,
|
|
1154
|
+
* no attrs and no edges. Each instance joins every group its block is in, so
|
|
1155
|
+
* a renderer draws it in the block's box. A block node whose entity carries
|
|
1156
|
+
* an `instanceRollup` (#4489) gets it. Pure. Returns `ir` itself when no
|
|
1157
|
+
* entity has instance keys or a rollup, so a graph with none prints what it
|
|
1158
|
+
* did before.
|
|
1159
|
+
*
|
|
1160
|
+
* Called by `chant graph` and the declared half of `--live`, not by
|
|
1161
|
+
* {@link buildGraphIr}, so `chant search`, which reads the base IR, still
|
|
1162
|
+
* counts blocks.
|
|
1163
|
+
*/
|
|
1164
|
+
export function withInstanceNodes(ir: GraphIR, entities: ReadonlyMap<string, Declarable>): GraphIR {
|
|
1165
|
+
const byId = new Map(ir.nodes.map((n) => [n.id, n]));
|
|
1166
|
+
const added: IRNode[] = [];
|
|
1167
|
+
const childrenOf = new Map<string, string[]>();
|
|
1168
|
+
const rolledUp = new Map<string, InstanceRollup>();
|
|
1169
|
+
for (const [name, entity] of entities) {
|
|
1170
|
+
const block = byId.get(name);
|
|
1171
|
+
if (!block || block.instanceOf) continue;
|
|
1172
|
+
const rollup = entityInstanceRollup(entity);
|
|
1173
|
+
if (rollup) rolledUp.set(name, rollup);
|
|
1174
|
+
for (const { id, key, scope } of entityInstances(name, entity)) {
|
|
1175
|
+
if (byId.has(id)) continue;
|
|
1176
|
+
const node: IRNode = {
|
|
1177
|
+
id,
|
|
1178
|
+
kind: block.kind,
|
|
1179
|
+
lexicon: block.lexicon,
|
|
1180
|
+
attrs: {},
|
|
1181
|
+
instanceOf: name,
|
|
1182
|
+
...(key !== undefined ? { instanceKey: key } : {}),
|
|
1183
|
+
...(scope !== undefined ? { instanceScope: scope } : {}),
|
|
1184
|
+
};
|
|
1185
|
+
if (block.sourceLoc) node.sourceLoc = { ...block.sourceLoc };
|
|
1186
|
+
if (block.compositeParent) node.compositeParent = block.compositeParent;
|
|
1187
|
+
if (block.compositeInstance) node.compositeInstance = block.compositeInstance;
|
|
1188
|
+
added.push(node);
|
|
1189
|
+
byId.set(id, node);
|
|
1190
|
+
(childrenOf.get(name) ?? childrenOf.set(name, []).get(name)!).push(id);
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
if (added.length === 0 && rolledUp.size === 0) return ir;
|
|
1194
|
+
const own = ir.nodes.map((n) => {
|
|
1195
|
+
const rollup = rolledUp.get(n.id);
|
|
1196
|
+
return rollup ? { ...n, instanceRollup: rollup } : n;
|
|
1197
|
+
});
|
|
1198
|
+
if (added.length === 0) return { ...ir, nodes: own };
|
|
1199
|
+
const nodes = [...own, ...added].sort((a, b) => a.id.localeCompare(b.id));
|
|
1200
|
+
const withChildren = (rec: Record<string, string[]> | undefined): Record<string, string[]> | undefined => {
|
|
1201
|
+
if (!rec) return rec;
|
|
1202
|
+
const out: Record<string, string[]> = {};
|
|
1203
|
+
for (const [k, ids] of Object.entries(rec)) out[k] = [...ids, ...ids.flatMap((id) => childrenOf.get(id) ?? [])].sort();
|
|
1204
|
+
return out;
|
|
1205
|
+
};
|
|
1206
|
+
const groups: IRGroups = { ...ir.groups };
|
|
1207
|
+
for (const key of ["byLexicon", "byComposite", "byStack"] as const) {
|
|
1208
|
+
const grown = withChildren(ir.groups[key]);
|
|
1209
|
+
if (grown) groups[key] = grown;
|
|
1210
|
+
}
|
|
1211
|
+
return { ...ir, nodes, groups };
|
|
1212
|
+
}
|
|
1213
|
+
|
|
985
1214
|
/**
|
|
986
1215
|
* Add what the lexicons' `graphEdges` hooks reported (#3910) to a built IR.
|
|
987
1216
|
*
|
|
@@ -1152,10 +1381,39 @@ export function buildLiveGraphIr(observations: LiveObservation[]): GraphIR {
|
|
|
1152
1381
|
// ownership above, since `unowned`/`foreign`/`unknown` all mean "no
|
|
1153
1382
|
// declared owner", which is simply the absence of this field.
|
|
1154
1383
|
if (meta.ownerChain?.root === "declared") node.runtimeOwner = meta.ownerChain.entity;
|
|
1384
|
+
// An engine's facts (#4527) ride beside `physicalId`, as the engine gave them.
|
|
1385
|
+
if (meta.facts) node.facts = meta.facts;
|
|
1155
1386
|
nodes.push(node);
|
|
1156
1387
|
(byLexicon[lexicon] ??= []).push(name);
|
|
1157
1388
|
// A live lexicon maps to one deployable stack, same as the source IR.
|
|
1158
1389
|
(byStack[lexicon] ??= []).push(name);
|
|
1390
|
+
// Each present instance of a `count` or `for_each` block is a node of
|
|
1391
|
+
// its own under the block's (#4454), so the overlay paints it alone.
|
|
1392
|
+
// The block node above is the rollup. An absent or not-observed
|
|
1393
|
+
// instance is no live node: the overlay reads that off `instances`.
|
|
1394
|
+
// Under an expanded module call the id follows the declared graph's
|
|
1395
|
+
// rule (#4486, #4488), `estate/module.app[0]/aws_eip.pool[1]`, with
|
|
1396
|
+
// `instanceScope` and no `instanceKey` when only the call is expanded.
|
|
1397
|
+
for (const inst of meta.instances ?? []) {
|
|
1398
|
+
if (inst.verdict !== "present") continue;
|
|
1399
|
+
const id = observedInstanceNodeId(name, inst);
|
|
1400
|
+
if (id === undefined) continue;
|
|
1401
|
+
const child: IRNode = {
|
|
1402
|
+
id,
|
|
1403
|
+
kind: meta.type,
|
|
1404
|
+
lexicon,
|
|
1405
|
+
attrs: { address: inst.address, ...(inst.status ? { status: inst.status } : {}) },
|
|
1406
|
+
instanceOf: name,
|
|
1407
|
+
...(inst.key !== undefined ? { instanceKey: inst.key } : {}),
|
|
1408
|
+
...(inst.scope !== undefined ? { instanceScope: inst.scope } : {}),
|
|
1409
|
+
};
|
|
1410
|
+
if (inst.physicalId) child.physicalId = inst.physicalId;
|
|
1411
|
+
if (inst.ownership === "owned" || inst.ownership === "foreign") child.ownership = inst.ownership;
|
|
1412
|
+
if (inst.facts) child.facts = inst.facts;
|
|
1413
|
+
nodes.push(child);
|
|
1414
|
+
(byLexicon[lexicon] ??= []).push(id);
|
|
1415
|
+
(byStack[lexicon] ??= []).push(id);
|
|
1416
|
+
}
|
|
1159
1417
|
}
|
|
1160
1418
|
}
|
|
1161
1419
|
|
|
@@ -1178,7 +1436,9 @@ export function buildLiveGraphIr(observations: LiveObservation[]): GraphIR {
|
|
|
1178
1436
|
for (const observation of observations) {
|
|
1179
1437
|
for (const edge of observation.edges ?? []) {
|
|
1180
1438
|
if (!observedIds.has(edge.from) || !observedIds.has(edge.to)) continue;
|
|
1181
|
-
|
|
1439
|
+
// `grain` is in the key (#4527): a block edge and an instance edge
|
|
1440
|
+
// between the same pair stay two edges.
|
|
1441
|
+
const key = `${edge.from}\u0000${edge.to}\u0000${edge.viaAttr ?? ""}\u0000${edge.toAttr ?? ""}\u0000${edge.grain ?? ""}`;
|
|
1182
1442
|
if (seen.has(key)) continue;
|
|
1183
1443
|
seen.add(key);
|
|
1184
1444
|
edges.push(edge);
|
|
@@ -1188,7 +1448,8 @@ export function buildLiveGraphIr(observations: LiveObservation[]): GraphIR {
|
|
|
1188
1448
|
(a, b) =>
|
|
1189
1449
|
a.from.localeCompare(b.from) ||
|
|
1190
1450
|
a.to.localeCompare(b.to) ||
|
|
1191
|
-
(a.viaAttr ?? "").localeCompare(b.viaAttr ?? "")
|
|
1451
|
+
(a.viaAttr ?? "").localeCompare(b.viaAttr ?? "") ||
|
|
1452
|
+
(a.grain ?? "").localeCompare(b.grain ?? ""),
|
|
1192
1453
|
);
|
|
1193
1454
|
|
|
1194
1455
|
// Stack exports (#1279) land on the IR's `exports`, the same place the
|
|
@@ -1226,17 +1487,48 @@ export function collectUnobserved(observations: LiveObservation[]): Record<strin
|
|
|
1226
1487
|
* `runtime` = live, undeclared, owner chain reaches a declared entity (#1077). */
|
|
1227
1488
|
type OverlayNodeStatus = "good" | "warn" | "accent" | "neutral" | "runtime";
|
|
1228
1489
|
|
|
1490
|
+
/**
|
|
1491
|
+
* The overlay paint on one node. `_ownership` (#4534, behold#906 Q2) is
|
|
1492
|
+
* chant's own marker verdict, {@link IRNode.ownership}, beside `_status`, so
|
|
1493
|
+
* `chant search` answers ownership with no grammar of its own:
|
|
1494
|
+
* `attr:_ownership=foreign`, `--show _ownership`, `--count-by attr:_ownership`.
|
|
1495
|
+
* It is `owned` or `foreign`; absent means unknown (no marker channel on the
|
|
1496
|
+
* read, or a node nobody observed). It never reads `facts.ownership`, the
|
|
1497
|
+
* engine's verdict, which stays for display (#4520 Q1).
|
|
1498
|
+
*/
|
|
1229
1499
|
function tagStatus(n: IRNode, status: OverlayNodeStatus, unobserved?: UnobservedEntity): IRNode {
|
|
1230
1500
|
return {
|
|
1231
1501
|
...n,
|
|
1232
1502
|
attrs: {
|
|
1233
1503
|
...n.attrs,
|
|
1234
1504
|
_status: status,
|
|
1505
|
+
...(n.ownership ? { _ownership: n.ownership } : {}),
|
|
1235
1506
|
...(unobserved ? { _unobserved: unobserved.reason } : {}),
|
|
1236
1507
|
},
|
|
1237
1508
|
};
|
|
1238
1509
|
}
|
|
1239
1510
|
|
|
1511
|
+
/**
|
|
1512
|
+
* The paint for a declared instance node (#4454) the live graph has no node
|
|
1513
|
+
* for. Its block not observed: `neutral` with the block's reason, since the
|
|
1514
|
+
* rollup put the whole block there. Its block live with instances read: the
|
|
1515
|
+
* instance is not among them, so `accent`, pending. Its block live with no
|
|
1516
|
+
* instance read at all: `neutral`, since nothing said either way. Its block
|
|
1517
|
+
* absent: `accent`, like the block.
|
|
1518
|
+
*/
|
|
1519
|
+
function missingInstance(n: IRNode, live: ReadonlySet<string>, read: ReadonlySet<string>, unobserved: Record<string, UnobservedEntity>): IRNode {
|
|
1520
|
+
const block = n.instanceOf!;
|
|
1521
|
+
const u = unobserved[n.id] ?? unobserved[block];
|
|
1522
|
+
if (u) return tagStatus(n, "neutral", u);
|
|
1523
|
+
if (live.has(block) && !read.has(block)) return tagStatus(n, "neutral");
|
|
1524
|
+
return tagStatus(n, "accent");
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
/** The block ids some live instance node names (#4454): the blocks whose read reported instances. */
|
|
1528
|
+
function blocksWithInstances(live: GraphIR): Set<string> {
|
|
1529
|
+
return new Set(live.nodes.map((n) => n.instanceOf).filter((b): b is string => b !== undefined));
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1240
1532
|
/**
|
|
1241
1533
|
* Overlay the declared graph on the provisioned one (#780, `chant graph --live
|
|
1242
1534
|
* --overlay`) and classify each resource, tagging a `_status` a renderer colours:
|
|
@@ -1256,8 +1548,13 @@ export function overlayGraphs(live: GraphIR, declared: GraphIR, opts?: OverlayOp
|
|
|
1256
1548
|
const liveIds = new Set(live.nodes.map((n) => n.id));
|
|
1257
1549
|
const unobserved = opts?.unobserved ?? {};
|
|
1258
1550
|
|
|
1551
|
+
const read = blocksWithInstances(live);
|
|
1552
|
+
|
|
1259
1553
|
const nodes: IRNode[] = live.nodes.map((n) => {
|
|
1260
1554
|
const d = declaredById.get(n.id);
|
|
1555
|
+
// A live instance of a declared block whose expansion the source could
|
|
1556
|
+
// not count (`count = var.n`) is managed, never foreign (#4454).
|
|
1557
|
+
if (!d && n.instanceOf && declaredById.has(n.instanceOf)) return tagStatus(n, "good");
|
|
1261
1558
|
if (!d) return tagStatus(n, n.runtimeOwner ? "runtime" : "warn");
|
|
1262
1559
|
// A managed node keeps the composite it was declared in, so `--detail 1`
|
|
1263
1560
|
// collapses it with its siblings and rolls their status up (#4227).
|
|
@@ -1269,6 +1566,10 @@ export function overlayGraphs(live: GraphIR, declared: GraphIR, opts?: OverlayOp
|
|
|
1269
1566
|
});
|
|
1270
1567
|
for (const n of declared.nodes) {
|
|
1271
1568
|
if (liveIds.has(n.id)) continue;
|
|
1569
|
+
if (n.instanceOf) {
|
|
1570
|
+
nodes.push(missingInstance(n, liveIds, read, unobserved));
|
|
1571
|
+
continue;
|
|
1572
|
+
}
|
|
1272
1573
|
const u = unobserved[n.id];
|
|
1273
1574
|
nodes.push(u ? tagStatus(n, "neutral", u) : tagStatus(n, "accent"));
|
|
1274
1575
|
}
|
|
@@ -1287,7 +1588,7 @@ export function overlayGraphs(live: GraphIR, declared: GraphIR, opts?: OverlayOp
|
|
|
1287
1588
|
*
|
|
1288
1589
|
* Each declared node is classified against live observation and tagged `_status`:
|
|
1289
1590
|
* - **managed** (declared + provisioned) → `good`, carrying the observed
|
|
1290
|
-
* `physicalId` / `ownership` onto the declared node
|
|
1591
|
+
* `physicalId` / `ownership` / engine `facts` onto the declared node
|
|
1291
1592
|
* - **pending** (declared, provider confirmed absent) → `accent`
|
|
1292
1593
|
* - **unobserved** (declared, chant could not look — #1089) → `neutral`, with
|
|
1293
1594
|
* the reason on `_unobserved`. A wrong-cluster or unsupported-kind read used
|
|
@@ -1302,12 +1603,19 @@ export function overlayGraphs(live: GraphIR, declared: GraphIR, opts?: OverlayOp
|
|
|
1302
1603
|
*/
|
|
1303
1604
|
export function sourceOverlayGraphs(declared: GraphIR, live: GraphIR, opts?: OverlayOptions): GraphIR {
|
|
1304
1605
|
const liveById = new Map(live.nodes.map((n) => [n.id, n]));
|
|
1606
|
+
const liveIds = new Set(liveById.keys());
|
|
1305
1607
|
const declaredIds = new Set(declared.nodes.map((n) => n.id));
|
|
1306
|
-
|
|
1608
|
+
// A live instance of a declared block (#4454) the source could not count
|
|
1609
|
+
// is managed: appended `good`, and never foreign.
|
|
1610
|
+
const managedInstances = live.nodes.filter((n) => !declaredIds.has(n.id) && n.instanceOf !== undefined && declaredIds.has(n.instanceOf));
|
|
1611
|
+
const managedInstanceIds = new Set(managedInstances.map((n) => n.id));
|
|
1612
|
+
const foreignIds = new Set(live.nodes.filter((n) => !declaredIds.has(n.id) && !managedInstanceIds.has(n.id)).map((n) => n.id));
|
|
1307
1613
|
const unobserved = opts?.unobserved ?? {};
|
|
1614
|
+
const read = blocksWithInstances(live);
|
|
1308
1615
|
|
|
1309
1616
|
const nodes: IRNode[] = declared.nodes.map((n) => {
|
|
1310
1617
|
const obs = liveById.get(n.id);
|
|
1618
|
+
if (!obs && n.instanceOf) return missingInstance(n, liveIds, read, unobserved);
|
|
1311
1619
|
if (!obs) {
|
|
1312
1620
|
const u = unobserved[n.id];
|
|
1313
1621
|
// unobserved — declared, and nobody looked; not "pending"
|
|
@@ -1316,6 +1624,7 @@ export function sourceOverlayGraphs(declared: GraphIR, live: GraphIR, opts?: Ove
|
|
|
1316
1624
|
const merged: IRNode = { ...n }; // managed — carry the observed identity
|
|
1317
1625
|
if (obs.physicalId) merged.physicalId = obs.physicalId;
|
|
1318
1626
|
if (obs.ownership) merged.ownership = obs.ownership;
|
|
1627
|
+
if (obs.facts) merged.facts = obs.facts;
|
|
1319
1628
|
// ...and what was observed ABOUT it (#1279). The declared canvas holds what
|
|
1320
1629
|
// the source says; the observation holds what the account says, and a fact
|
|
1321
1630
|
// like `VpcId` exists only on the second. Dropping it here made every
|
|
@@ -1334,6 +1643,7 @@ export function sourceOverlayGraphs(declared: GraphIR, live: GraphIR, opts?: Ove
|
|
|
1334
1643
|
if (!foreignIds.has(n.id)) continue;
|
|
1335
1644
|
nodes.push(tagStatus(n, n.runtimeOwner ? "runtime" : "warn")); // runtime child or foreign
|
|
1336
1645
|
}
|
|
1646
|
+
for (const n of managedInstances) nodes.push(tagStatus(n, "good"));
|
|
1337
1647
|
nodes.sort((a, b) => a.id.localeCompare(b.id));
|
|
1338
1648
|
|
|
1339
1649
|
// Declared edges are the canvas (the cross-substrate topology). Add only the
|