@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,224 @@
|
|
|
1
|
+
import { type CoverageEntry, type IndexDocument } from "./index-document.js";
|
|
2
|
+
import type { SnapshotStore } from "./snapshot-store.js";
|
|
3
|
+
/** The first chant that exports the index diff and `chant index diff`. */
|
|
4
|
+
export declare const INDEX_DIFF_FLOOR = "0.124.54";
|
|
5
|
+
/**
|
|
6
|
+
* The words a comparison against an index uses (#4533, shared with #4526).
|
|
7
|
+
* `not-observed` is the drift record's word for the same thing
|
|
8
|
+
* (../drift-record.ts `DriftStatus`): the read could not say, and the
|
|
9
|
+
* coverage verdict says why.
|
|
10
|
+
*/
|
|
11
|
+
export type IndexChangeKind = "added" | "removed" | "changed" | "not-observed";
|
|
12
|
+
export declare const INDEX_CHANGE_KINDS: readonly IndexChangeKind[];
|
|
13
|
+
/** A coverage entry as the diff reads it: chant's `CoverageEntry`, or the same shape with any verdict string. */
|
|
14
|
+
export interface IndexDiffCoverageEntry {
|
|
15
|
+
listedType: string;
|
|
16
|
+
location: string;
|
|
17
|
+
verdict: CoverageEntry["verdict"] | (string & {});
|
|
18
|
+
detail?: string;
|
|
19
|
+
}
|
|
20
|
+
/** The parts of an index node the diff reads. An `IRNode` is one. */
|
|
21
|
+
export interface IndexDiffNode {
|
|
22
|
+
id: string;
|
|
23
|
+
kind: string;
|
|
24
|
+
lexicon?: string;
|
|
25
|
+
attrs?: Record<string, unknown>;
|
|
26
|
+
tags?: Record<string, string>;
|
|
27
|
+
listedType?: string;
|
|
28
|
+
location?: string;
|
|
29
|
+
nativeId?: string;
|
|
30
|
+
physicalId?: string;
|
|
31
|
+
}
|
|
32
|
+
/** The parts of an index edge the diff reads. An `IREdge` is one. */
|
|
33
|
+
export interface IndexDiffEdge {
|
|
34
|
+
from: string;
|
|
35
|
+
to: string;
|
|
36
|
+
kind?: string;
|
|
37
|
+
viaAttr?: string;
|
|
38
|
+
relation?: string;
|
|
39
|
+
origin?: string;
|
|
40
|
+
rule?: string;
|
|
41
|
+
}
|
|
42
|
+
/** The parts of an index version the diff reads. An {@link IndexDocument} is one. */
|
|
43
|
+
export interface IndexDiffDocument {
|
|
44
|
+
index: string;
|
|
45
|
+
stamp: {
|
|
46
|
+
scopeKey: string;
|
|
47
|
+
observedAt: string;
|
|
48
|
+
completedAt?: string;
|
|
49
|
+
digest: string;
|
|
50
|
+
source?: {
|
|
51
|
+
kind: string;
|
|
52
|
+
name: string;
|
|
53
|
+
version?: string;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
coverage: readonly IndexDiffCoverageEntry[];
|
|
57
|
+
graph: {
|
|
58
|
+
nodes: readonly IndexDiffNode[];
|
|
59
|
+
edges: readonly IndexDiffEdge[];
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/** Two versions of different scopes. Refused by name, never diffed. */
|
|
63
|
+
export declare class IndexScopeMismatch extends Error {
|
|
64
|
+
readonly fromScopeKey: string;
|
|
65
|
+
readonly toScopeKey: string;
|
|
66
|
+
readonly code = "index-scope-mismatch";
|
|
67
|
+
constructor(fromScopeKey: string, toScopeKey: string);
|
|
68
|
+
}
|
|
69
|
+
/** A document that is not an index version, or a reference no store holds. */
|
|
70
|
+
export declare class NotAnIndexVersion extends Error {
|
|
71
|
+
readonly code = "not-an-index-version";
|
|
72
|
+
constructor(message: string);
|
|
73
|
+
}
|
|
74
|
+
export interface IndexDiffStamp {
|
|
75
|
+
scopeKey: string;
|
|
76
|
+
observedAt: string;
|
|
77
|
+
completedAt?: string;
|
|
78
|
+
digest: string;
|
|
79
|
+
source?: {
|
|
80
|
+
kind: string;
|
|
81
|
+
name: string;
|
|
82
|
+
version?: string;
|
|
83
|
+
};
|
|
84
|
+
/** The version name, when the caller knows it. */
|
|
85
|
+
version?: string;
|
|
86
|
+
}
|
|
87
|
+
export interface IndexNodeRef {
|
|
88
|
+
key: string;
|
|
89
|
+
kind: string;
|
|
90
|
+
listedType: string;
|
|
91
|
+
location: string;
|
|
92
|
+
}
|
|
93
|
+
export interface IndexPropertyChange {
|
|
94
|
+
path: string;
|
|
95
|
+
before?: unknown;
|
|
96
|
+
after?: unknown;
|
|
97
|
+
}
|
|
98
|
+
export interface IndexNodeChanged extends IndexNodeRef {
|
|
99
|
+
properties: IndexPropertyChange[];
|
|
100
|
+
}
|
|
101
|
+
/** A node one read has and the other did not observe. `side` names the read that did not observe it. */
|
|
102
|
+
export interface IndexNodeNotObserved extends IndexNodeRef {
|
|
103
|
+
side: "from" | "to";
|
|
104
|
+
/** The coverage verdict for its (type, location) in that read, or `not-in-coverage`. */
|
|
105
|
+
verdict: string;
|
|
106
|
+
detail?: string;
|
|
107
|
+
}
|
|
108
|
+
export interface IndexEdgeRef {
|
|
109
|
+
from: string;
|
|
110
|
+
to: string;
|
|
111
|
+
kind: string;
|
|
112
|
+
viaAttr?: string;
|
|
113
|
+
relation: string;
|
|
114
|
+
origin?: string;
|
|
115
|
+
rule?: string;
|
|
116
|
+
}
|
|
117
|
+
export interface IndexEdgeNotObserved extends IndexEdgeRef {
|
|
118
|
+
side: "from" | "to";
|
|
119
|
+
/** The end whose (type, location) was not observed in that read. */
|
|
120
|
+
unobservedEnd: string;
|
|
121
|
+
verdict: string;
|
|
122
|
+
}
|
|
123
|
+
export interface IndexDiff {
|
|
124
|
+
diff: "v1";
|
|
125
|
+
scopeKey: string;
|
|
126
|
+
from: IndexDiffStamp;
|
|
127
|
+
to: IndexDiffStamp;
|
|
128
|
+
/** Same digest: same graph and coverage. */
|
|
129
|
+
unchanged: boolean;
|
|
130
|
+
nodes: {
|
|
131
|
+
added: IndexNodeRef[];
|
|
132
|
+
removed: IndexNodeRef[];
|
|
133
|
+
changed: IndexNodeChanged[];
|
|
134
|
+
notObserved: IndexNodeNotObserved[];
|
|
135
|
+
};
|
|
136
|
+
edges: {
|
|
137
|
+
added: IndexEdgeRef[];
|
|
138
|
+
removed: IndexEdgeRef[];
|
|
139
|
+
notObserved: IndexEdgeNotObserved[];
|
|
140
|
+
};
|
|
141
|
+
/** (type, location) pairs whose verdict moved between the reads. */
|
|
142
|
+
coverage: Array<{
|
|
143
|
+
listedType: string;
|
|
144
|
+
location: string;
|
|
145
|
+
before?: string;
|
|
146
|
+
after?: string;
|
|
147
|
+
}>;
|
|
148
|
+
counts: {
|
|
149
|
+
added: number;
|
|
150
|
+
removed: number;
|
|
151
|
+
changed: number;
|
|
152
|
+
properties: number;
|
|
153
|
+
notObserved: number;
|
|
154
|
+
edgesAdded: number;
|
|
155
|
+
edgesRemoved: number;
|
|
156
|
+
edgesNotObserved: number;
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
export interface IndexDiffOptions {
|
|
160
|
+
/** Version names, for the stamps. */
|
|
161
|
+
fromVersion?: string;
|
|
162
|
+
toVersion?: string;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* A node's (type, location): its own `listedType` and `location` (#4521
|
|
166
|
+
* writes both), else the path-style id's fourth and third segments
|
|
167
|
+
* (behold#1025 Q2, `<substrate>/<scopeId>/<location>/<listedType>/<nativeId>`),
|
|
168
|
+
* else its kind at every location.
|
|
169
|
+
*/
|
|
170
|
+
export declare function indexNodeTypeAndLocation(n: IndexDiffNode): {
|
|
171
|
+
listedType: string;
|
|
172
|
+
location: string;
|
|
173
|
+
};
|
|
174
|
+
/** What an index's coverage says about a (type, location) that holds no node. */
|
|
175
|
+
export type IndexAbsence = {
|
|
176
|
+
kind: "removed";
|
|
177
|
+
} | {
|
|
178
|
+
kind: "not-observed";
|
|
179
|
+
verdict: string;
|
|
180
|
+
detail?: string;
|
|
181
|
+
};
|
|
182
|
+
/**
|
|
183
|
+
* The rule for an absent node (#4533, shared with #4526): absent counts as
|
|
184
|
+
* gone (`removed`) only where the read's coverage says `listed` for the
|
|
185
|
+
* node's (type, location); anywhere else it is `not-observed`, with the
|
|
186
|
+
* verdict, or `not-in-coverage` when no entry speaks for it.
|
|
187
|
+
*/
|
|
188
|
+
export declare function indexAbsence(coverage: readonly IndexDiffCoverageEntry[], listedType: string, location: string): IndexAbsence;
|
|
189
|
+
/** The property changes of one node between two reads. */
|
|
190
|
+
export declare function indexNodePropertyChanges(before: IndexDiffNode, after: IndexDiffNode): IndexPropertyChange[];
|
|
191
|
+
/**
|
|
192
|
+
* What changed from `from` to `to`, two versions of one index scope.
|
|
193
|
+
* Throws {@link IndexScopeMismatch} when their scope keys differ, and
|
|
194
|
+
* {@link NotAnIndexVersion} for a document of another shape.
|
|
195
|
+
*/
|
|
196
|
+
export declare function diffIndexVersions(from: IndexDiffDocument, to: IndexDiffDocument, o?: IndexDiffOptions): IndexDiff;
|
|
197
|
+
/** A parsed version reference: `<scopeKey>/<version>`, or `<scopeKey>` alone for its latest. */
|
|
198
|
+
export interface IndexVersionRef {
|
|
199
|
+
scopeKey: string;
|
|
200
|
+
/** Absent: the scope's latest version. */
|
|
201
|
+
version?: string;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Parse `<scopeKey>/<version>` or `<scopeKey>`. A bare version name (no
|
|
205
|
+
* scope) takes `inScope`'s scope, so `--against <version>` can name another
|
|
206
|
+
* version of the first argument's scope.
|
|
207
|
+
*/
|
|
208
|
+
export declare function parseIndexVersionRef(ref: string, inScope?: string): IndexVersionRef;
|
|
209
|
+
/** One version read from a store, with the name it is stored under. */
|
|
210
|
+
export interface StoredIndexVersion {
|
|
211
|
+
scopeKey: string;
|
|
212
|
+
version: string;
|
|
213
|
+
doc: IndexDocument;
|
|
214
|
+
}
|
|
215
|
+
/** Read one version (or a scope's latest) through the store. Throws {@link NotAnIndexVersion} when the store has none. */
|
|
216
|
+
export declare function readIndexVersionRef(store: Pick<SnapshotStore, "kind" | "listIndex" | "readIndexAt">, ref: IndexVersionRef): Promise<StoredIndexVersion>;
|
|
217
|
+
/**
|
|
218
|
+
* Diff two stored versions. `to` absent: `from` names a scope (or a version
|
|
219
|
+
* in one), and the diff is the scope's last two versions, or the version
|
|
220
|
+
* before `from` against `from`. Two references under different scope paths
|
|
221
|
+
* are refused before either is read.
|
|
222
|
+
*/
|
|
223
|
+
export declare function diffIndexVersionRefs(store: Pick<SnapshotStore, "kind" | "listIndex" | "readIndexAt">, from: IndexVersionRef, to?: IndexVersionRef): Promise<IndexDiff>;
|
|
224
|
+
//# sourceMappingURL=index-diff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-diff.d.ts","sourceRoot":"","sources":["../../src/lifecycle/index-diff.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What changed between two versions of one index scope (#4533, moved from
|
|
3
|
+
* INTENTIUS/behold#1028's src/graph-db/index-diff.ts under the ruling that
|
|
4
|
+
* behold is a control plane and every model lives in chant,
|
|
5
|
+
* INTENTIUS/behold#1024).
|
|
6
|
+
*
|
|
7
|
+
* A pure function over two index versions (./index-document.ts): nodes added
|
|
8
|
+
* and removed, properties changed, edges added and removed. It reads nothing
|
|
9
|
+
* and writes nothing; {@link readIndexVersionRef} and
|
|
10
|
+
* {@link diffIndexVersionRefs} load the two versions through a
|
|
11
|
+
* {@link SnapshotStore}, so every store kind (git ref, local, s3) diffs the
|
|
12
|
+
* same way.
|
|
13
|
+
*
|
|
14
|
+
* The lifecycle deep diff (./deep-diff.ts) compares a declared tree with a
|
|
15
|
+
* live one, and a live path no declaration claims is "unclaimed" there rather
|
|
16
|
+
* than a change. Two index versions are both observed, so this comparison is
|
|
17
|
+
* symmetric.
|
|
18
|
+
*
|
|
19
|
+
* Rules:
|
|
20
|
+
*
|
|
21
|
+
* - One scope per diff. Two versions whose `stamp.scopeKey` differ are
|
|
22
|
+
* refused by name with {@link IndexScopeMismatch}: a node missing from one
|
|
23
|
+
* could just be out of its scope.
|
|
24
|
+
* - A node is removed only when the later read listed its (type, location).
|
|
25
|
+
* Otherwise it is `not-observed` in that read, with the coverage verdict
|
|
26
|
+
* that says why. The other way round, a node is added only when the earlier
|
|
27
|
+
* read listed its (type, location). Coverage is looked up with
|
|
28
|
+
* {@link indexCoverageFor}, where `"*"` matches every type or location.
|
|
29
|
+
* {@link indexAbsence} is that rule on its own, for #4526's drift from an
|
|
30
|
+
* index, so both read "absent" the same way.
|
|
31
|
+
* - An edge is removed (or added) only when both its ends were observed in
|
|
32
|
+
* the read that lacks it; otherwise it is `not-observed`.
|
|
33
|
+
* - Properties: `kind`, and each leaf path of `attrs` (arrays compare as
|
|
34
|
+
* whole values). `tags` is compared only for a node whose `attrs` show no
|
|
35
|
+
* change, because a lister's tags are a projection of the listed
|
|
36
|
+
* properties: one tag edit is one changed property, not two. `facts` is
|
|
37
|
+
* never compared (its `observedAt` moves on every read).
|
|
38
|
+
* - Two versions with the same `stamp.digest` hold the same graph and
|
|
39
|
+
* coverage: the diff is `unchanged` and nothing is walked.
|
|
40
|
+
*/
|
|
41
|
+
import { NEXT_RELEASE } from "../release-floors.js";
|
|
42
|
+
import { indexCoverageFor, isIndexVersionName } from "./index-document.js";
|
|
43
|
+
/** The first chant that exports the index diff and `chant index diff`. */
|
|
44
|
+
export const INDEX_DIFF_FLOOR = NEXT_RELEASE;
|
|
45
|
+
export const INDEX_CHANGE_KINDS = ["added", "removed", "changed", "not-observed"];
|
|
46
|
+
/** Two versions of different scopes. Refused by name, never diffed. */
|
|
47
|
+
export class IndexScopeMismatch extends Error {
|
|
48
|
+
constructor(fromScopeKey, toScopeKey) {
|
|
49
|
+
super(`refused: the two index versions have different scopes (${fromScopeKey} and ${toScopeKey}), and a node missing from one could just be out of its scope. Diff two versions of one scope.`);
|
|
50
|
+
this.fromScopeKey = fromScopeKey;
|
|
51
|
+
this.toScopeKey = toScopeKey;
|
|
52
|
+
this.code = "index-scope-mismatch";
|
|
53
|
+
this.name = "IndexScopeMismatch";
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/** A document that is not an index version, or a reference no store holds. */
|
|
57
|
+
export class NotAnIndexVersion extends Error {
|
|
58
|
+
constructor(message) {
|
|
59
|
+
super(message);
|
|
60
|
+
this.code = "not-an-index-version";
|
|
61
|
+
this.name = "NotAnIndexVersion";
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/** The inverse of index-document.ts encodeIndexSegment; a segment that is not percent-encoded comes back as it is. */
|
|
65
|
+
function decodeSegment(s) {
|
|
66
|
+
try {
|
|
67
|
+
return decodeURIComponent(s);
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return s;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* A node's (type, location): its own `listedType` and `location` (#4521
|
|
75
|
+
* writes both), else the path-style id's fourth and third segments
|
|
76
|
+
* (behold#1025 Q2, `<substrate>/<scopeId>/<location>/<listedType>/<nativeId>`),
|
|
77
|
+
* else its kind at every location.
|
|
78
|
+
*/
|
|
79
|
+
export function indexNodeTypeAndLocation(n) {
|
|
80
|
+
if (n.listedType && n.location)
|
|
81
|
+
return { listedType: n.listedType, location: n.location };
|
|
82
|
+
const parts = n.id.split("/");
|
|
83
|
+
if (parts.length >= 5)
|
|
84
|
+
return { listedType: n.listedType ?? decodeSegment(parts[3]), location: n.location ?? decodeSegment(parts[2]) };
|
|
85
|
+
return { listedType: n.listedType ?? n.kind, location: n.location ?? "*" };
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* The rule for an absent node (#4533, shared with #4526): absent counts as
|
|
89
|
+
* gone (`removed`) only where the read's coverage says `listed` for the
|
|
90
|
+
* node's (type, location); anywhere else it is `not-observed`, with the
|
|
91
|
+
* verdict, or `not-in-coverage` when no entry speaks for it.
|
|
92
|
+
*/
|
|
93
|
+
export function indexAbsence(coverage, listedType, location) {
|
|
94
|
+
const e = indexCoverageFor(coverage, listedType, location);
|
|
95
|
+
if (e?.verdict === "listed")
|
|
96
|
+
return { kind: "removed" };
|
|
97
|
+
return e ? { kind: "not-observed", verdict: e.verdict, ...(e.detail ? { detail: e.detail } : {}) } : { kind: "not-observed", verdict: "not-in-coverage" };
|
|
98
|
+
}
|
|
99
|
+
function stampOf(doc, version) {
|
|
100
|
+
const s = doc.stamp;
|
|
101
|
+
return {
|
|
102
|
+
scopeKey: s.scopeKey,
|
|
103
|
+
observedAt: s.observedAt,
|
|
104
|
+
...(s.completedAt ? { completedAt: s.completedAt } : {}),
|
|
105
|
+
digest: s.digest,
|
|
106
|
+
...(s.source ? { source: s.source } : {}),
|
|
107
|
+
...(version ? { version } : {}),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
function check(doc, which) {
|
|
111
|
+
if (!doc || doc.index !== "v1" || typeof doc.stamp?.scopeKey !== "string" || !Array.isArray(doc.graph?.nodes)) {
|
|
112
|
+
throw new NotAnIndexVersion(`the ${which} document is not an index version (index: "v1" with a stamp and a graph)`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
const isPlain = (v) => !!v && typeof v === "object" && !Array.isArray(v);
|
|
116
|
+
/** JSON with keys sorted, so equal values compare equal. */
|
|
117
|
+
function canon(v) {
|
|
118
|
+
return JSON.stringify(v, (_k, x) => (isPlain(x) ? Object.fromEntries(Object.entries(x).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))) : x)) ?? "undefined";
|
|
119
|
+
}
|
|
120
|
+
/** Leaf paths of an object; arrays and scalars are leaves. */
|
|
121
|
+
function leaves(v, prefix, out) {
|
|
122
|
+
if (isPlain(v) && Object.keys(v).length > 0) {
|
|
123
|
+
for (const [k, x] of Object.entries(v))
|
|
124
|
+
leaves(x, prefix ? `${prefix}.${k}` : k, out);
|
|
125
|
+
}
|
|
126
|
+
else if (prefix) {
|
|
127
|
+
out.set(prefix, v);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
function changedPaths(before, after, root) {
|
|
131
|
+
const a = new Map();
|
|
132
|
+
const b = new Map();
|
|
133
|
+
leaves(before ?? {}, root, a);
|
|
134
|
+
leaves(after ?? {}, root, b);
|
|
135
|
+
const out = [];
|
|
136
|
+
for (const path of [...new Set([...a.keys(), ...b.keys()])].sort()) {
|
|
137
|
+
const x = a.get(path);
|
|
138
|
+
const y = b.get(path);
|
|
139
|
+
if (canon(x) === canon(y))
|
|
140
|
+
continue;
|
|
141
|
+
out.push({ path, ...(a.has(path) ? { before: x } : {}), ...(b.has(path) ? { after: y } : {}) });
|
|
142
|
+
}
|
|
143
|
+
return out;
|
|
144
|
+
}
|
|
145
|
+
/** The property changes of one node between two reads. */
|
|
146
|
+
export function indexNodePropertyChanges(before, after) {
|
|
147
|
+
const out = [];
|
|
148
|
+
if (before.kind !== after.kind)
|
|
149
|
+
out.push({ path: "kind", before: before.kind, after: after.kind });
|
|
150
|
+
const attrs = changedPaths(before.attrs, after.attrs, "attrs");
|
|
151
|
+
out.push(...attrs);
|
|
152
|
+
if (attrs.length === 0)
|
|
153
|
+
out.push(...changedPaths(before.tags, after.tags, "tags"));
|
|
154
|
+
return out;
|
|
155
|
+
}
|
|
156
|
+
function edgeKey(e) {
|
|
157
|
+
return [e.from, e.to, e.kind ?? "", e.viaAttr ?? "", e.relation ?? "reference"].join("\u0000");
|
|
158
|
+
}
|
|
159
|
+
function edgeRef(e) {
|
|
160
|
+
return {
|
|
161
|
+
from: e.from,
|
|
162
|
+
to: e.to,
|
|
163
|
+
kind: e.kind ?? "",
|
|
164
|
+
...(e.viaAttr ? { viaAttr: e.viaAttr } : {}),
|
|
165
|
+
relation: e.relation ?? "reference",
|
|
166
|
+
...(e.origin ? { origin: e.origin } : {}),
|
|
167
|
+
...(e.rule ? { rule: e.rule } : {}),
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
const refOf = (n) => ({ key: n.id, kind: n.kind, ...indexNodeTypeAndLocation(n) });
|
|
171
|
+
const byKey = ([a], [b]) => (a < b ? -1 : a > b ? 1 : 0);
|
|
172
|
+
/**
|
|
173
|
+
* What changed from `from` to `to`, two versions of one index scope.
|
|
174
|
+
* Throws {@link IndexScopeMismatch} when their scope keys differ, and
|
|
175
|
+
* {@link NotAnIndexVersion} for a document of another shape.
|
|
176
|
+
*/
|
|
177
|
+
export function diffIndexVersions(from, to, o = {}) {
|
|
178
|
+
check(from, "first");
|
|
179
|
+
check(to, "second");
|
|
180
|
+
if (from.stamp.scopeKey !== to.stamp.scopeKey)
|
|
181
|
+
throw new IndexScopeMismatch(from.stamp.scopeKey, to.stamp.scopeKey);
|
|
182
|
+
const out = {
|
|
183
|
+
diff: "v1",
|
|
184
|
+
scopeKey: from.stamp.scopeKey,
|
|
185
|
+
from: stampOf(from, o.fromVersion),
|
|
186
|
+
to: stampOf(to, o.toVersion),
|
|
187
|
+
unchanged: false,
|
|
188
|
+
nodes: { added: [], removed: [], changed: [], notObserved: [] },
|
|
189
|
+
edges: { added: [], removed: [], notObserved: [] },
|
|
190
|
+
coverage: [],
|
|
191
|
+
counts: { added: 0, removed: 0, changed: 0, properties: 0, notObserved: 0, edgesAdded: 0, edgesRemoved: 0, edgesNotObserved: 0 },
|
|
192
|
+
};
|
|
193
|
+
if (from.stamp.digest && from.stamp.digest === to.stamp.digest) {
|
|
194
|
+
out.unchanged = true;
|
|
195
|
+
return out;
|
|
196
|
+
}
|
|
197
|
+
const absence = (doc, n) => {
|
|
198
|
+
const { listedType, location } = indexNodeTypeAndLocation(n);
|
|
199
|
+
return indexAbsence(doc.coverage, listedType, location);
|
|
200
|
+
};
|
|
201
|
+
const unobserved = (n, a, side) => ({
|
|
202
|
+
...refOf(n),
|
|
203
|
+
side,
|
|
204
|
+
verdict: a.verdict,
|
|
205
|
+
...(a.detail ? { detail: a.detail } : {}),
|
|
206
|
+
});
|
|
207
|
+
const before = new Map(from.graph.nodes.map((n) => [n.id, n]));
|
|
208
|
+
const after = new Map(to.graph.nodes.map((n) => [n.id, n]));
|
|
209
|
+
for (const [id, n] of [...before].sort(byKey)) {
|
|
210
|
+
const m = after.get(id);
|
|
211
|
+
if (m) {
|
|
212
|
+
const properties = indexNodePropertyChanges(n, m);
|
|
213
|
+
if (properties.length > 0)
|
|
214
|
+
out.nodes.changed.push({ ...refOf(m), properties });
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
const a = absence(to, n);
|
|
218
|
+
if (a.kind === "removed")
|
|
219
|
+
out.nodes.removed.push(refOf(n));
|
|
220
|
+
else
|
|
221
|
+
out.nodes.notObserved.push(unobserved(n, a, "to"));
|
|
222
|
+
}
|
|
223
|
+
for (const [id, n] of [...after].sort(byKey)) {
|
|
224
|
+
if (before.has(id))
|
|
225
|
+
continue;
|
|
226
|
+
const a = absence(from, n);
|
|
227
|
+
if (a.kind === "removed")
|
|
228
|
+
out.nodes.added.push(refOf(n));
|
|
229
|
+
else
|
|
230
|
+
out.nodes.notObserved.push(unobserved(n, a, "from"));
|
|
231
|
+
}
|
|
232
|
+
// An edge's ends are looked up in either read: a removed edge's ends may be gone from `to`.
|
|
233
|
+
const nodeFor = (id) => after.get(id) ?? before.get(id) ?? { id, kind: "" };
|
|
234
|
+
const edgesIn = (doc) => new Map(doc.graph.edges.map((e) => [edgeKey(e), e]));
|
|
235
|
+
const ea = edgesIn(from);
|
|
236
|
+
const eb = edgesIn(to);
|
|
237
|
+
const classify = (e, lacking, side, into) => {
|
|
238
|
+
for (const end of [e.from, e.to]) {
|
|
239
|
+
const a = absence(lacking, nodeFor(end));
|
|
240
|
+
if (a.kind === "not-observed") {
|
|
241
|
+
out.edges.notObserved.push({ ...edgeRef(e), side, unobservedEnd: end, verdict: a.verdict });
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
into.push(edgeRef(e));
|
|
246
|
+
};
|
|
247
|
+
for (const [k, e] of [...ea].sort(byKey))
|
|
248
|
+
if (!eb.has(k))
|
|
249
|
+
classify(e, to, "to", out.edges.removed);
|
|
250
|
+
for (const [k, e] of [...eb].sort(byKey))
|
|
251
|
+
if (!ea.has(k))
|
|
252
|
+
classify(e, from, "from", out.edges.added);
|
|
253
|
+
const cov = new Map();
|
|
254
|
+
for (const e of from.coverage)
|
|
255
|
+
cov.set(`${e.listedType}\u0000${e.location}`, { listedType: e.listedType, location: e.location, before: e.verdict });
|
|
256
|
+
for (const e of to.coverage) {
|
|
257
|
+
const k = `${e.listedType}\u0000${e.location}`;
|
|
258
|
+
cov.set(k, { ...(cov.get(k) ?? { listedType: e.listedType, location: e.location }), after: e.verdict });
|
|
259
|
+
}
|
|
260
|
+
out.coverage = [...cov.values()]
|
|
261
|
+
.filter((c) => c.before !== c.after)
|
|
262
|
+
.sort((a, b) => (a.listedType + "\u0000" + a.location < b.listedType + "\u0000" + b.location ? -1 : 1));
|
|
263
|
+
out.counts = {
|
|
264
|
+
added: out.nodes.added.length,
|
|
265
|
+
removed: out.nodes.removed.length,
|
|
266
|
+
changed: out.nodes.changed.length,
|
|
267
|
+
properties: out.nodes.changed.reduce((s, c) => s + c.properties.length, 0),
|
|
268
|
+
notObserved: out.nodes.notObserved.length,
|
|
269
|
+
edgesAdded: out.edges.added.length,
|
|
270
|
+
edgesRemoved: out.edges.removed.length,
|
|
271
|
+
edgesNotObserved: out.edges.notObserved.length,
|
|
272
|
+
};
|
|
273
|
+
return out;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Parse `<scopeKey>/<version>` or `<scopeKey>`. A bare version name (no
|
|
277
|
+
* scope) takes `inScope`'s scope, so `--against <version>` can name another
|
|
278
|
+
* version of the first argument's scope.
|
|
279
|
+
*/
|
|
280
|
+
export function parseIndexVersionRef(ref, inScope) {
|
|
281
|
+
const trimmed = ref.replace(/^\/+|\/+$/g, "");
|
|
282
|
+
const slash = trimmed.lastIndexOf("/");
|
|
283
|
+
const last = slash < 0 ? trimmed : trimmed.slice(slash + 1);
|
|
284
|
+
if (isIndexVersionName(last)) {
|
|
285
|
+
if (slash >= 0)
|
|
286
|
+
return { scopeKey: trimmed.slice(0, slash), version: last };
|
|
287
|
+
if (!inScope)
|
|
288
|
+
throw new NotAnIndexVersion(`"${ref}" is a version name with no scope: name it as <scopeKey>/${last}`);
|
|
289
|
+
return { scopeKey: inScope, version: last };
|
|
290
|
+
}
|
|
291
|
+
if (!trimmed)
|
|
292
|
+
throw new NotAnIndexVersion("an empty index version reference");
|
|
293
|
+
return { scopeKey: trimmed };
|
|
294
|
+
}
|
|
295
|
+
/** Read one version (or a scope's latest) through the store. Throws {@link NotAnIndexVersion} when the store has none. */
|
|
296
|
+
export async function readIndexVersionRef(store, ref) {
|
|
297
|
+
const version = ref.version ?? (await store.listIndex(ref.scopeKey)).pop();
|
|
298
|
+
if (!version)
|
|
299
|
+
throw new NotAnIndexVersion(`the ${store.kind} store holds no index version under ${ref.scopeKey}`);
|
|
300
|
+
const doc = await store.readIndexAt(ref.scopeKey, version);
|
|
301
|
+
if (!doc)
|
|
302
|
+
throw new NotAnIndexVersion(`the ${store.kind} store holds no index version ${ref.scopeKey}/${version}`);
|
|
303
|
+
return { scopeKey: ref.scopeKey, version, doc };
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Diff two stored versions. `to` absent: `from` names a scope (or a version
|
|
307
|
+
* in one), and the diff is the scope's last two versions, or the version
|
|
308
|
+
* before `from` against `from`. Two references under different scope paths
|
|
309
|
+
* are refused before either is read.
|
|
310
|
+
*/
|
|
311
|
+
export async function diffIndexVersionRefs(store, from, to) {
|
|
312
|
+
let a = from;
|
|
313
|
+
let b = to;
|
|
314
|
+
if (!b) {
|
|
315
|
+
const versions = await store.listIndex(from.scopeKey);
|
|
316
|
+
const at = from.version ? versions.indexOf(from.version) : versions.length - 1;
|
|
317
|
+
if (at < 1)
|
|
318
|
+
throw new NotAnIndexVersion(`the ${store.kind} store holds no version before ${from.version ?? "the latest"} under ${from.scopeKey}: name two versions`);
|
|
319
|
+
a = { scopeKey: from.scopeKey, version: versions[at - 1] };
|
|
320
|
+
b = { scopeKey: from.scopeKey, version: versions[at] };
|
|
321
|
+
}
|
|
322
|
+
if (a.scopeKey !== b.scopeKey)
|
|
323
|
+
throw new IndexScopeMismatch(a.scopeKey, b.scopeKey);
|
|
324
|
+
const x = await readIndexVersionRef(store, a);
|
|
325
|
+
const y = await readIndexVersionRef(store, b);
|
|
326
|
+
return diffIndexVersions(x.doc, y.doc, { fromVersion: x.version, toVersion: y.version });
|
|
327
|
+
}
|