@intentius/chant 0.101.0 → 0.102.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/checks.d.ts.map +1 -1
- package/dist/attrref.d.ts.map +1 -1
- package/dist/audit/discover.d.ts.map +1 -1
- package/dist/audit/nginx.d.ts.map +1 -1
- package/dist/audit/prior-art.d.ts +48 -0
- package/dist/audit/prior-art.d.ts.map +1 -1
- package/dist/behaviour-kinds.d.ts.map +1 -1
- package/dist/builder.d.ts.map +1 -1
- package/dist/cli/commands/carve-emit.d.ts.map +1 -1
- package/dist/cli/commands/check-lexicon.d.ts +16 -0
- package/dist/cli/commands/check-lexicon.d.ts.map +1 -1
- package/dist/cli/commands/import.d.ts +8 -0
- package/dist/cli/commands/import.d.ts.map +1 -1
- package/dist/cli/commands/init-lexicon.d.ts.map +1 -1
- package/dist/cli/commands/init.d.ts +19 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/onboard.d.ts +9 -0
- package/dist/cli/commands/onboard.d.ts.map +1 -1
- package/dist/cli/commands/pinned-upgrade.d.ts +19 -5
- package/dist/cli/commands/pinned-upgrade.d.ts.map +1 -1
- package/dist/cli/handlers/dev.d.ts.map +1 -1
- package/dist/cli/handlers/lifecycle.d.ts.map +1 -1
- package/dist/cli/handlers/misc.d.ts.map +1 -1
- package/dist/cli/handlers/operator.d.ts +9 -0
- package/dist/cli/handlers/operator.d.ts.map +1 -1
- package/dist/cli/handlers/run.d.ts.map +1 -1
- package/dist/cli/lsp/server.d.ts.map +1 -1
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/mcp/server.d.ts.map +1 -1
- package/dist/cli/mcp/tools/build.d.ts.map +1 -1
- package/dist/cli/mcp/tools/composites.d.ts.map +1 -1
- package/dist/cli/mcp/tools/explain.d.ts.map +1 -1
- package/dist/cli/mcp/tools/import.d.ts.map +1 -1
- package/dist/cli/mcp/tools/lint.d.ts.map +1 -1
- package/dist/cli/mcp/tools/scaffold.d.ts.map +1 -1
- package/dist/cli/mcp/tools/search.d.ts.map +1 -1
- package/dist/cli/mcp/workspace-tools.d.ts +1 -1
- package/dist/cli/mcp/workspace-tools.d.ts.map +1 -1
- package/dist/cli/registry.d.ts +11 -2
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/codegen/fetch.d.ts.map +1 -1
- package/dist/codegen/naming.d.ts.map +1 -1
- package/dist/codegen/pinned-upgrade.d.ts +67 -3
- package/dist/codegen/pinned-upgrade.d.ts.map +1 -1
- package/dist/codegen/registry.d.ts.map +1 -1
- package/dist/components/capability-plugin-loader.d.ts.map +1 -1
- package/dist/components/capability.d.ts.map +1 -1
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/fan-out.d.ts.map +1 -1
- package/dist/components/starter-plugin.d.ts.map +1 -1
- package/dist/components/verbs/process-runner.d.ts.map +1 -1
- package/dist/components/verbs/r2-sync.d.ts.map +1 -1
- package/dist/components/verbs/run-agent.d.ts.map +1 -1
- package/dist/components/verbs/sbom-generator.d.ts.map +1 -1
- package/dist/components/verbs/sign.d.ts.map +1 -1
- package/dist/components/verbs/verify.d.ts.map +1 -1
- package/dist/components/verbs/vuln-gate.d.ts.map +1 -1
- package/dist/components/verbs/vuln-scan.d.ts.map +1 -1
- package/dist/components/verbs/wrangler.d.ts.map +1 -1
- package/dist/composite.d.ts.map +1 -1
- package/dist/config.d.ts +19 -7
- package/dist/config.d.ts.map +1 -1
- package/dist/declarable.d.ts +16 -0
- package/dist/declarable.d.ts.map +1 -1
- package/dist/discovery/cache.d.ts.map +1 -1
- package/dist/discovery/fold-import.d.ts +15 -5
- package/dist/discovery/fold-import.d.ts.map +1 -1
- package/dist/discovery/param-deps.d.ts +16 -0
- package/dist/discovery/param-deps.d.ts.map +1 -1
- package/dist/discovery/sandbox/policy-wire.d.ts.map +1 -1
- package/dist/discovery/specifier-resolve.d.ts +37 -0
- package/dist/discovery/specifier-resolve.d.ts.map +1 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/fold/fold.d.ts +3 -1
- package/dist/fold/fold.d.ts.map +1 -1
- package/dist/graph-detail.d.ts.map +1 -1
- package/dist/graph-ir.d.ts.map +1 -1
- package/dist/graph-layout.d.ts.map +1 -1
- package/dist/import/base-parser.d.ts.map +1 -1
- package/dist/import/embedded.d.ts +7 -0
- package/dist/import/embedded.d.ts.map +1 -1
- package/dist/import/parser-options.d.ts +14 -0
- package/dist/import/parser-options.d.ts.map +1 -0
- package/dist/import/parser.d.ts +17 -0
- package/dist/import/parser.d.ts.map +1 -1
- package/dist/kubectl-context.d.ts.map +1 -1
- package/dist/lexicon-output.d.ts.map +1 -1
- package/dist/lexicon-schema.d.ts +3 -3
- package/dist/lexicon.d.ts +55 -3
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/lifecycle/assert-live.d.ts.map +1 -1
- package/dist/lifecycle/gate-ledger.d.ts +15 -0
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
- package/dist/lifecycle/git.d.ts.map +1 -1
- package/dist/lifecycle/member-ledger.d.ts.map +1 -1
- package/dist/lifecycle/observe.d.ts.map +1 -1
- package/dist/lifecycle/plan-ledger.d.ts.map +1 -1
- package/dist/lifecycle/release-ledger.d.ts.map +1 -1
- package/dist/lifecycle/scenario.d.ts.map +1 -1
- package/dist/lifecycle/status.d.ts.map +1 -1
- package/dist/lifecycle/work-lease.d.ts +61 -2
- package/dist/lifecycle/work-lease.d.ts.map +1 -1
- package/dist/lint/config.d.ts +8 -8
- package/dist/lint/engine.d.ts +6 -0
- package/dist/lint/engine.d.ts.map +1 -1
- package/dist/lsp/lexicon-providers.d.ts.map +1 -1
- package/dist/op/activities/activity-contracts.d.ts +11 -11
- package/dist/op/activities/apply.d.ts +79 -9
- package/dist/op/activities/apply.d.ts.map +1 -1
- package/dist/op/activities/decide.d.ts.map +1 -1
- package/dist/op/activities/index.d.ts +1 -1
- package/dist/op/activities/index.d.ts.map +1 -1
- package/dist/op/activities/lexicon-upgrade.d.ts +44 -12
- package/dist/op/activities/lexicon-upgrade.d.ts.map +1 -1
- package/dist/op/activity-contract.d.ts +1 -1
- package/dist/op/activity-failure.d.ts.map +1 -1
- package/dist/op/activity-profiles.d.ts.map +1 -1
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/composites/apply-op.d.ts +12 -5
- package/dist/op/composites/apply-op.d.ts.map +1 -1
- package/dist/op/composites/lexicon-upgrade-op.d.ts +22 -6
- package/dist/op/composites/lexicon-upgrade-op.d.ts.map +1 -1
- package/dist/op/decide-backend.d.ts.map +1 -1
- package/dist/op/decide-read-inputs.d.ts.map +1 -1
- package/dist/op/emulator-lifecycle.d.ts +21 -2
- package/dist/op/emulator-lifecycle.d.ts.map +1 -1
- package/dist/op/gate-approval.d.ts +5 -1
- package/dist/op/gate-approval.d.ts.map +1 -1
- package/dist/op/gate-wait.d.ts.map +1 -1
- package/dist/op/gate.d.ts +19 -3
- package/dist/op/gate.d.ts.map +1 -1
- package/dist/op/index.d.ts +2 -0
- package/dist/op/index.d.ts.map +1 -1
- package/dist/op/local-executor.d.ts +6 -0
- package/dist/op/local-executor.d.ts.map +1 -1
- package/dist/op/operator.d.ts.map +1 -1
- package/dist/op/run-context.d.ts +39 -0
- package/dist/op/run-context.d.ts.map +1 -0
- package/dist/op/run-live.d.ts.map +1 -1
- package/dist/op/runtimes/local.d.ts.map +1 -1
- package/dist/op/source-archive.d.ts.map +1 -1
- package/dist/op/steward-beside.d.ts.map +1 -1
- package/dist/op/steward-points.d.ts.map +1 -1
- package/dist/op/steward.d.ts.map +1 -1
- package/dist/op/types.d.ts +8 -3
- package/dist/op/types.d.ts.map +1 -1
- package/dist/op/work-lease-run.d.ts +24 -4
- package/dist/op/work-lease-run.d.ts.map +1 -1
- package/dist/project-root.d.ts.map +1 -1
- package/dist/provenance.d.ts +21 -0
- package/dist/provenance.d.ts.map +1 -1
- package/dist/pseudo-parameter.d.ts.map +1 -1
- package/dist/reconcile.d.ts.map +1 -1
- package/dist/secret-materialization.d.ts.map +1 -1
- package/dist/terraform/emit-source.d.ts.map +1 -1
- package/dist/terraform/parse.d.ts.map +1 -1
- package/dist/testing.d.ts.map +1 -1
- package/dist/workspace/__fixtures__/contract-repo.d.ts.map +1 -1
- package/dist/workspace/__fixtures__/decide-workspace.d.ts +1 -1
- package/dist/workspace/__fixtures__/decide-workspace.d.ts.map +1 -1
- package/dist/workspace/agent-cli.d.ts +5 -0
- package/dist/workspace/agent-cli.d.ts.map +1 -1
- package/dist/workspace/box-factory.d.ts +73 -0
- package/dist/workspace/box-factory.d.ts.map +1 -0
- package/dist/workspace/changes.d.ts.map +1 -1
- package/dist/workspace/chant-migrations/chud-lexicon-exit.d.ts.map +1 -1
- package/dist/workspace/checks/boxes.d.ts.map +1 -1
- package/dist/workspace/checks.d.ts +5 -0
- package/dist/workspace/checks.d.ts.map +1 -1
- package/dist/workspace/compose-graph.d.ts +10 -0
- package/dist/workspace/compose-graph.d.ts.map +1 -1
- package/dist/workspace/conformance/index.d.ts +67 -6
- package/dist/workspace/conformance/index.d.ts.map +1 -1
- package/dist/workspace/conformance/vitest.d.ts +12 -3
- package/dist/workspace/conformance/vitest.d.ts.map +1 -1
- package/dist/workspace/conformance/writer.d.ts +368 -0
- package/dist/workspace/conformance/writer.d.ts.map +1 -0
- package/dist/workspace/decide.d.ts +1 -1
- package/dist/workspace/decide.d.ts.map +1 -1
- package/dist/workspace/declaration.d.ts +91 -4
- package/dist/workspace/declaration.d.ts.map +1 -1
- package/dist/workspace/declaration.schema.json +234 -5
- package/dist/workspace/generated-files.d.ts.map +1 -1
- package/dist/workspace/graph-cache.d.ts.map +1 -1
- package/dist/workspace/graph-cli.d.ts +2 -0
- package/dist/workspace/graph-cli.d.ts.map +1 -1
- package/dist/workspace/identity.d.ts +111 -0
- package/dist/workspace/identity.d.ts.map +1 -0
- package/dist/workspace/intent-cli.d.ts +7 -4
- package/dist/workspace/intent-cli.d.ts.map +1 -1
- package/dist/workspace/intent-record.d.ts +8 -1
- package/dist/workspace/intent-record.d.ts.map +1 -1
- package/dist/workspace/intent.d.ts +149 -5
- package/dist/workspace/intent.d.ts.map +1 -1
- package/dist/workspace/kinds.d.ts +18 -4
- package/dist/workspace/kinds.d.ts.map +1 -1
- package/dist/workspace/lineage-hash-index.d.ts.map +1 -1
- package/dist/workspace/lineage-lock.d.ts +2 -2
- package/dist/workspace/lineage-lock.d.ts.map +1 -1
- package/dist/workspace/links.d.ts.map +1 -1
- package/dist/workspace/points.d.ts.map +1 -1
- package/dist/workspace/principal-classes.d.ts +114 -0
- package/dist/workspace/principal-classes.d.ts.map +1 -0
- package/dist/workspace/reason-codes.d.ts +21 -1
- package/dist/workspace/reason-codes.d.ts.map +1 -1
- package/dist/workspace/record-assets.d.ts.map +1 -1
- package/dist/workspace/records-checkout.d.ts +54 -0
- package/dist/workspace/records-checkout.d.ts.map +1 -0
- package/dist/workspace/records-cli.d.ts +27 -1
- package/dist/workspace/records-cli.d.ts.map +1 -1
- package/dist/workspace/records-close.d.ts +1 -1
- package/dist/workspace/records-close.d.ts.map +1 -1
- package/dist/workspace/records-since.d.ts.map +1 -1
- package/dist/workspace/records-write.d.ts +5 -4
- package/dist/workspace/records-write.d.ts.map +1 -1
- package/dist/workspace/records.d.ts +15 -0
- package/dist/workspace/records.d.ts.map +1 -1
- package/dist/workspace/runs-cli.d.ts +164 -0
- package/dist/workspace/runs-cli.d.ts.map +1 -0
- package/dist/workspace/runs.d.ts +423 -0
- package/dist/workspace/runs.d.ts.map +1 -0
- package/dist/workspace/source-block.d.ts +1 -1
- package/dist/workspace/source-block.d.ts.map +1 -1
- package/dist/workspace/status-gates.d.ts +15 -3
- package/dist/workspace/status-gates.d.ts.map +1 -1
- package/dist/workspace/status.d.ts +10 -0
- package/dist/workspace/status.d.ts.map +1 -1
- package/dist/workspace/symbols.d.ts +52 -0
- package/dist/workspace/symbols.d.ts.map +1 -0
- package/dist/workspace/trailer-joins.d.ts +46 -0
- package/dist/workspace/trailer-joins.d.ts.map +1 -0
- package/dist/workspace/trailers.d.ts +89 -0
- package/dist/workspace/trailers.d.ts.map +1 -0
- package/dist/workspace/trust/attestor.d.ts.map +1 -1
- package/dist/workspace/trust/rotation.d.ts.map +1 -1
- package/dist/workspace/trust/seal.d.ts +33 -0
- package/dist/workspace/trust/seal.d.ts.map +1 -1
- package/dist/workspace/trust/test-repo.d.ts.map +1 -1
- package/dist/workspace/work-cli.d.ts +39 -3
- package/dist/workspace/work-cli.d.ts.map +1 -1
- package/dist/workspace/work-evidence.d.ts +1 -1
- package/dist/workspace/work-evidence.d.ts.map +1 -1
- package/dist/workspace/work.d.ts +26 -1
- package/dist/workspace/work.d.ts.map +1 -1
- package/dist/workspace/workspace-principals.schema.json +60 -0
- package/dist/workspace/write-scope.d.ts +79 -19
- package/dist/workspace/write-scope.d.ts.map +1 -1
- package/dist/yaml.d.ts +21 -39
- package/dist/yaml.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/audit/prior-art.ts +15 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/package.json +1 -1
- package/src/cli/commands/carve-emit-state.test.ts +4 -0
- package/src/cli/commands/carve-emit.ts +5 -19
- package/src/cli/commands/check-lexicon.test.ts +62 -1
- package/src/cli/commands/check-lexicon.ts +36 -6
- package/src/cli/commands/import-live.test.ts +18 -0
- package/src/cli/commands/import-parser-options.test.ts +133 -0
- package/src/cli/commands/import.ts +21 -3
- package/src/cli/commands/init-lexicon/templates/project.ts +1 -1
- package/src/cli/commands/init.test.ts +8 -1
- package/src/cli/commands/init.ts +23 -8
- package/src/cli/commands/lint.test.ts +37 -0
- package/src/cli/commands/onboard.test.ts +53 -3
- package/src/cli/commands/onboard.ts +52 -4
- package/src/cli/commands/pinned-upgrade.ts +73 -33
- package/src/cli/handlers/__snapshots__/build-member.test.ts.snap +2 -2
- package/src/cli/handlers/components.ts +2 -2
- package/src/cli/handlers/dev.ts +8 -6
- package/src/cli/handlers/lifecycle.test.ts +67 -0
- package/src/cli/handlers/lifecycle.ts +6 -5
- package/src/cli/handlers/misc.ts +2 -0
- package/src/cli/handlers/operator.ts +87 -3
- package/src/cli/handlers/run.test.ts +111 -0
- package/src/cli/handlers/run.ts +85 -24
- package/src/cli/handlers/scenario.ts +2 -2
- package/src/cli/main.test.ts +1 -0
- package/src/cli/main.ts +65 -11
- package/src/cli/mcp/workspace-tools.test.ts +5 -2
- package/src/cli/mcp/workspace-tools.ts +29 -2
- package/src/cli/registry.ts +11 -2
- package/src/codegen/pinned-upgrade-multi.test.ts +157 -0
- package/src/codegen/pinned-upgrade-tags.test.ts +112 -0
- package/src/codegen/pinned-upgrade.test.ts +104 -0
- package/src/codegen/pinned-upgrade.ts +250 -56
- package/src/codegen/testdata/postgres-tags.json +242 -0
- package/src/config.test.ts +21 -0
- package/src/config.ts +15 -0
- package/src/declarable.test.ts +21 -0
- package/src/declarable.ts +19 -0
- package/src/discovery/fold-composite.test.ts +41 -5
- package/src/discovery/fold-import.test.ts +129 -0
- package/src/discovery/fold-import.ts +643 -131
- package/src/discovery/fold-package-composite.test.ts +264 -0
- package/src/discovery/fold-specifiers.test.ts +191 -0
- package/src/discovery/param-deps.test.ts +66 -1
- package/src/discovery/param-deps.ts +45 -0
- package/src/discovery/specifier-resolve.ts +344 -0
- package/src/fold/fold.test.ts +39 -1
- package/src/fold/fold.ts +83 -9
- package/src/fold-provenance.test.ts +140 -0
- package/src/graph-ir.test.ts +83 -0
- package/src/graph-ir.ts +29 -0
- package/src/import/embedded.test.ts +20 -0
- package/src/import/embedded.ts +13 -0
- package/src/import/parser-options.ts +46 -0
- package/src/import/parser.ts +20 -0
- package/src/lexicon.ts +55 -3
- package/src/lifecycle/gate-ledger.ts +16 -0
- package/src/lifecycle/observe.test.ts +18 -0
- package/src/lifecycle/observe.ts +6 -4
- package/src/lifecycle/snapshot.ts +2 -2
- package/src/lifecycle/work-lease.test.ts +1 -1
- package/src/lifecycle/work-lease.ts +93 -2
- package/src/lint/engine.test.ts +55 -0
- package/src/lint/engine.ts +30 -4
- package/src/lint/output-docs.test.ts +59 -56
- package/src/op/activities/apply.test.ts +189 -5
- package/src/op/activities/apply.ts +230 -8
- package/src/op/activities/index.ts +3 -0
- package/src/op/activities/lexicon-upgrade.test.ts +160 -6
- package/src/op/activities/lexicon-upgrade.ts +154 -51
- package/src/op/composites/apply-op.ts +12 -5
- package/src/op/composites/composites.test.ts +30 -3
- package/src/op/composites/lexicon-upgrade-op.test.ts +7 -2
- package/src/op/composites/lexicon-upgrade-op.ts +29 -8
- package/src/op/emulator-lifecycle.test.ts +23 -0
- package/src/op/emulator-lifecycle.ts +52 -14
- package/src/op/gate-approval.test.ts +74 -0
- package/src/op/gate-approval.ts +5 -1
- package/src/op/gate.ts +31 -5
- package/src/op/index.ts +2 -0
- package/src/op/local-executor.test.ts +15 -0
- package/src/op/local-executor.ts +40 -12
- package/src/op/local-output.ts +1 -1
- package/src/op/operator.ts +4 -0
- package/src/op/run-context.test.ts +141 -0
- package/src/op/run-context.ts +51 -0
- package/src/op/runtimes/local.test.ts +14 -0
- package/src/op/runtimes/local.ts +2 -0
- package/src/op/steward-beside.ts +2 -0
- package/src/op/types.ts +8 -3
- package/src/op/work-lease-run.test.ts +47 -0
- package/src/op/work-lease-run.ts +73 -11
- package/src/provenance.ts +35 -0
- package/src/workspace/__fixtures__/studio-template-84c8b21.json +1 -1
- package/src/workspace/agent-cli.ts +7 -3
- package/src/workspace/agent.schema.json +22 -0
- package/src/workspace/box-factory.test.ts +320 -0
- package/src/workspace/box-factory.ts +103 -0
- package/src/workspace/changes.schema.json +12 -20
- package/src/workspace/changes.ts +4 -1
- package/src/workspace/checks/boxes.test.ts +2 -0
- package/src/workspace/checks.ts +29 -5
- package/src/workspace/compose-graph.ts +7 -0
- package/src/workspace/conformance/__writer_fixture__/answers/answer.kind.mjs +27 -0
- package/src/workspace/conformance/__writer_fixture__/answers/answer.schema.json +95 -0
- package/src/workspace/conformance/__writer_fixture__/decisions/points.json +132 -0
- package/src/workspace/conformance/__writer_fixture__/sessions/session.kind.mjs +48 -0
- package/src/workspace/conformance/__writer_fixture__/sessions/session.schema.json +108 -0
- package/src/workspace/conformance/__writer_fixture__/work/W-001-the-writer-suite-works-this-item.md +25 -0
- package/src/workspace/conformance/__writer_fixture__/work/work.kind.mjs +60 -0
- package/src/workspace/conformance/__writer_fixture__/work/work.schema.json +578 -0
- package/src/workspace/conformance/conformance.e2e.test.ts +35 -3
- package/src/workspace/conformance/index.mjs +30 -3
- package/src/workspace/conformance/index.ts +103 -15
- package/src/workspace/conformance/vitest.ts +44 -2
- package/src/workspace/conformance/writer-conformance.e2e.test.ts +131 -0
- package/src/workspace/conformance/writer.test.ts +156 -0
- package/src/workspace/conformance/writer.ts +880 -0
- package/src/workspace/decide.ts +7 -1
- package/src/workspace/declaration.schema.json +234 -5
- package/src/workspace/declaration.ts +174 -10
- package/src/workspace/graph-cli.ts +5 -2
- package/src/workspace/graph.schema.json +247 -0
- package/src/workspace/identity.test.ts +196 -0
- package/src/workspace/identity.ts +186 -0
- package/src/workspace/intent-cli.ts +64 -10
- package/src/workspace/intent-record.schema.json +208 -0
- package/src/workspace/intent-record.ts +35 -1
- package/src/workspace/intent-why.test.ts +274 -0
- package/src/workspace/intent.schema.json +718 -7
- package/src/workspace/intent.test.ts +11 -2
- package/src/workspace/intent.ts +495 -32
- package/src/workspace/kinds.ts +44 -37
- package/src/workspace/points-write.schema.json +1 -0
- package/src/workspace/principal-classes.test.ts +175 -0
- package/src/workspace/principal-classes.ts +307 -0
- package/src/workspace/reason-codes.test.ts +11 -3
- package/src/workspace/reason-codes.ts +24 -1
- package/src/workspace/records-amend.schema.json +2 -0
- package/src/workspace/records-checkout.ts +106 -0
- package/src/workspace/records-cli.ts +103 -11
- package/src/workspace/records-close.schema.json +1 -0
- package/src/workspace/records-new.schema.json +2 -0
- package/src/workspace/records-review.schema.json +2 -0
- package/src/workspace/records-uncommitted.test.ts +171 -0
- package/src/workspace/records-write.ts +28 -6
- package/src/workspace/records.schema.json +72 -1
- package/src/workspace/records.ts +27 -0
- package/src/workspace/runs-cli.ts +381 -0
- package/src/workspace/runs-write.schema.json +583 -0
- package/src/workspace/runs.schema.json +810 -0
- package/src/workspace/runs.test.ts +242 -0
- package/src/workspace/runs.ts +709 -0
- package/src/workspace/status-contract.test.ts +5 -0
- package/src/workspace/status-gates.ts +22 -8
- package/src/workspace/status.schema.json +127 -2
- package/src/workspace/status.ts +21 -1
- package/src/workspace/symbols.ts +180 -0
- package/src/workspace/trailer-joins.test.ts +171 -0
- package/src/workspace/trailer-joins.ts +82 -0
- package/src/workspace/trailers.ts +148 -0
- package/src/workspace/trust/seal.ts +52 -1
- package/src/workspace/work-cli.e2e.test.ts +28 -1
- package/src/workspace/work-cli.ts +133 -8
- package/src/workspace/work-evidence.schema.json +2 -0
- package/src/workspace/work-history.schema.json +73 -1
- package/src/workspace/work-history.test.ts +48 -5
- package/src/workspace/work-kind-fields.test.ts +154 -0
- package/src/workspace/work-lease.schema.json +14 -1
- package/src/workspace/work.ts +82 -0
- package/src/workspace/workspace-principals.schema.json +60 -0
- package/src/workspace/write-scope.test.ts +128 -2
- package/src/workspace/write-scope.ts +170 -45
- package/src/yaml.test.ts +111 -1
- package/src/yaml.ts +141 -549
|
@@ -21,6 +21,14 @@
|
|
|
21
21
|
* per-resource `gcpApply` and the fly lexicon's `flyApply`, which never had a
|
|
22
22
|
* CLI in the path to begin with: gcp maps each CNRM kind to its REST API
|
|
23
23
|
* itself, and fly speaks the Machines API (flaps) directly, no flyctl.
|
|
24
|
+
* `grafana` joined later (#3011): the grafana lexicon's `grafanaApply`, which
|
|
25
|
+
* writes folders, library panels and dashboards over Grafana's HTTP API.
|
|
26
|
+
* `clickhouse` joined after it (#3208): the sql lexicon's `clickhouseApply`,
|
|
27
|
+
* which sends a ClickHouse server the CREATE and ALTER statements a build's
|
|
28
|
+
* classified changes need, over its HTTP interface. `postgres` joined after
|
|
29
|
+
* that (#3280): the sql lexicon's `postgresApply`, which sends a Postgres
|
|
30
|
+
* server the statements a build's classified changes need, grouped into
|
|
31
|
+
* transactions, with `CONCURRENTLY` statements outside them.
|
|
24
32
|
* **The dispatcher stayed here**, because "which
|
|
25
33
|
* mechanism applies this target" is not any one product's knowledge — and
|
|
26
34
|
* because the activity keeps its name, its arguments and its place in
|
|
@@ -40,7 +48,7 @@ import { importLexiconPackage } from "../../lexicon-module";
|
|
|
40
48
|
const execAsync = promisify(exec);
|
|
41
49
|
|
|
42
50
|
/** The native apply mechanism for a target. */
|
|
43
|
-
export type ApplyTarget = "cloudformation" | "kubectl" | "arm" | "kustomize" | "gcp" | "fly";
|
|
51
|
+
export type ApplyTarget = "cloudformation" | "kubectl" | "arm" | "kustomize" | "gcp" | "fly" | "grafana" | "clickhouse" | "postgres";
|
|
44
52
|
|
|
45
53
|
/**
|
|
46
54
|
* How apply treats resources no longer declared.
|
|
@@ -52,7 +60,16 @@ export type ApplyTarget = "cloudformation" | "kubectl" | "arm" | "kustomize" | "
|
|
|
52
60
|
* ownership label (via the gcp lexicon's `gcpApply` — only kinds it can
|
|
53
61
|
* list; the rest are reported not-prunable), `fly` prunes machines by the
|
|
54
62
|
* metadata marker and the metadata-less types (volumes/ips/certs/secrets)
|
|
55
|
-
* app-scoped under a managed app (via the fly lexicon's `flyApply`),
|
|
63
|
+
* app-scoped under a managed app (via the fly lexicon's `flyApply`),
|
|
64
|
+
* `grafana` prunes dashboards and folders by the ownership labels (via the
|
|
65
|
+
* grafana lexicon's `grafanaApply`; library panels, Grafana 11 and a project
|
|
66
|
+
* with no ownership stack are reported not-prunable), `clickhouse` drops
|
|
67
|
+
* tables, views and databases whose comment carries the project's marker
|
|
68
|
+
* (via the sql lexicon's `clickhouseApply`; a project with no ownership
|
|
69
|
+
* stack is reported not-prunable), `postgres` drops the objects in the
|
|
70
|
+
* declared schemas whose comment carries the project's marker (via the sql
|
|
71
|
+
* lexicon's `postgresApply`; never an object another tool keeps, and a
|
|
72
|
+
* project with no ownership stack is reported not-prunable), and
|
|
56
73
|
* `cloudformation` is bounded by the stack — which holds, because a
|
|
57
74
|
* resource CFN did not create is not in the stack.
|
|
58
75
|
* - `gated` — same delete scope as `owned-only`, but an approval gate precedes
|
|
@@ -66,7 +83,11 @@ export interface NativeApplyArgs {
|
|
|
66
83
|
target: ApplyTarget;
|
|
67
84
|
/** Environment. What it means is per target: the CFN stack name on
|
|
68
85
|
* `cloudformation`, the ARM resource group on `arm`, the chant environment
|
|
69
|
-
* on `kubectl`/`kustomize
|
|
86
|
+
* on `kubectl`/`kustomize`, and on `grafana` the chant environment whose
|
|
87
|
+
* `grafana.profiles.<env>` names the Grafana to write to, and on
|
|
88
|
+
* `clickhouse` and `postgres` the chant environment whose
|
|
89
|
+
* `sql.profiles.<env>` names the server. On `gcp` and
|
|
90
|
+
* `fly` it is a log label only — the
|
|
70
91
|
* gcp applier resolves the project (`GOOGLE_CLOUD_PROJECT` env / CNRM
|
|
71
92
|
* annotation) and endpoint (`GCP_ENDPOINT_URL` env) itself, and the fly
|
|
72
93
|
* applier resolves its endpoint (`FLY_FLAPS_BASE_URL` env) and token
|
|
@@ -74,7 +95,9 @@ export interface NativeApplyArgs {
|
|
|
74
95
|
env: string;
|
|
75
96
|
/** Built manifest/template path. Default per target ({@link defaultOutput}):
|
|
76
97
|
* `dist` (a dir) for kubectl, `template.json` (a file) for
|
|
77
|
-
* CloudFormation/ARM, `dist/gcp.yaml` for gcp, `dist/fly.json` for fly
|
|
98
|
+
* CloudFormation/ARM, `dist/gcp.yaml` for gcp, `dist/fly.json` for fly,
|
|
99
|
+
* `dist/grafana.json` (the build index) for grafana, `dist/schema.json`
|
|
100
|
+
* (the sql lexicon's build output) for clickhouse and postgres. */
|
|
78
101
|
output?: string;
|
|
79
102
|
/** Delete handling. Default: never. */
|
|
80
103
|
deleteMode?: DeleteMode;
|
|
@@ -182,6 +205,57 @@ export type FlyApplier = (
|
|
|
182
205
|
signal?: AbortSignal,
|
|
183
206
|
) => Promise<ApplyResult>;
|
|
184
207
|
|
|
208
|
+
/**
|
|
209
|
+
* The grafana lexicon's API applier, as this module needs to call it (#3011):
|
|
210
|
+
* `grafanaApply` composed with the lexicon's own `toApplyResult` projection,
|
|
211
|
+
* so what crosses this seam is core's versioned apply envelope (#1446).
|
|
212
|
+
*
|
|
213
|
+
* `environment` selects `grafana.profiles.<environment>` (else `GRAFANA_URL`
|
|
214
|
+
* with `GRAFANA_TOKEN`), the binding observe and export use. The ownership
|
|
215
|
+
* marker is not passed: `grafanaApply` reads `ownership` from the project's
|
|
216
|
+
* `chant.config.ts` itself, and a prune without a stack declines as
|
|
217
|
+
* not-prunable rather than delete another project's dashboards.
|
|
218
|
+
*/
|
|
219
|
+
export type GrafanaApplier = (
|
|
220
|
+
args: {
|
|
221
|
+
indexPath: string;
|
|
222
|
+
environment?: string;
|
|
223
|
+
prune?: boolean;
|
|
224
|
+
},
|
|
225
|
+
signal?: AbortSignal,
|
|
226
|
+
) => Promise<ApplyResult>;
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* The sql lexicon's ClickHouse applier, as this module needs to call it
|
|
230
|
+
* (#3208): `clickhouseApply` composed with the lexicon's own `toApplyResult`
|
|
231
|
+
* projection, so what crosses this seam is core's versioned apply envelope
|
|
232
|
+
* (#1446). A rebuild-class change rides it as NOT-ATTEMPTED.
|
|
233
|
+
*
|
|
234
|
+
* `environment` selects `sql.profiles.<environment>` (else `CLICKHOUSE_URL`),
|
|
235
|
+
* the binding observe and import use. The ownership marker is not passed:
|
|
236
|
+
* `clickhouseApply` reads `ownership` from the project's `chant.config.ts`.
|
|
237
|
+
*/
|
|
238
|
+
export type ClickHouseApplier = (
|
|
239
|
+
args: {
|
|
240
|
+
buildPath: string;
|
|
241
|
+
environment?: string;
|
|
242
|
+
prune?: boolean;
|
|
243
|
+
},
|
|
244
|
+
signal?: AbortSignal,
|
|
245
|
+
) => Promise<ApplyResult>;
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* The sql lexicon's Postgres applier, as this module needs to call it
|
|
249
|
+
* (#3280): `postgresApply` composed with the lexicon's own `toApplyResult`,
|
|
250
|
+
* the same seam as {@link ClickHouseApplier}. An expand-and-contract change
|
|
251
|
+
* and a rolled-back transaction's objects ride it as NOT-ATTEMPTED.
|
|
252
|
+
*
|
|
253
|
+
* `environment` selects `sql.profiles.<environment>` (else `POSTGRES_URL`).
|
|
254
|
+
* The ownership marker and the timeouts are not passed: `postgresApply`
|
|
255
|
+
* reads `ownership` and the profile from the project's `chant.config.ts`.
|
|
256
|
+
*/
|
|
257
|
+
export type PostgresApplier = ClickHouseApplier;
|
|
258
|
+
|
|
185
259
|
/**
|
|
186
260
|
* The aws lexicon's CloudFormation applier, as this module needs to call it
|
|
187
261
|
* (#1449). Structural, like {@link K8sApplier} and {@link AzureApplier}.
|
|
@@ -363,6 +437,102 @@ async function loadFlyApplier(): Promise<FlyApplier> {
|
|
|
363
437
|
return async (args, signal) => toApplyResult(await flyApply(args, signal));
|
|
364
438
|
}
|
|
365
439
|
|
|
440
|
+
/**
|
|
441
|
+
* Load the grafana lexicon's `grafanaApply` (#3011). Same variable-specifier
|
|
442
|
+
* trick as {@link loadK8sApplier}, for the same reason. The activities subpath,
|
|
443
|
+
* not the package root or `op/builders`: those hold the typed step builder,
|
|
444
|
+
* while the activity itself (and its `toApplyResult`) lives here.
|
|
445
|
+
*/
|
|
446
|
+
async function loadGrafanaApplier(): Promise<GrafanaApplier> {
|
|
447
|
+
const spec = "@intentius/chant-lexicon-grafana/op/activities";
|
|
448
|
+
type GrafanaModule = {
|
|
449
|
+
grafanaApply?: (args: Parameters<GrafanaApplier>[0], signal?: AbortSignal) => Promise<unknown>;
|
|
450
|
+
toApplyResult?: (result: unknown) => ApplyResult;
|
|
451
|
+
};
|
|
452
|
+
let mod: GrafanaModule;
|
|
453
|
+
try {
|
|
454
|
+
mod = (await importLexiconPackage(spec)) as GrafanaModule;
|
|
455
|
+
} catch (err) {
|
|
456
|
+
throw new Error(
|
|
457
|
+
`apply target "grafana" needs @intentius/chant-lexicon-grafana, which could not be loaded ` +
|
|
458
|
+
`(${err instanceof Error ? err.message : String(err)}). Grafana applies go through the grafana ` +
|
|
459
|
+
`lexicon's API applier (chant #2948); install the grafana lexicon and list it in chant.config.ts.`,
|
|
460
|
+
);
|
|
461
|
+
}
|
|
462
|
+
const { grafanaApply, toApplyResult } = mod;
|
|
463
|
+
if (typeof grafanaApply !== "function") {
|
|
464
|
+
throw new Error(
|
|
465
|
+
"the installed @intentius/chant-lexicon-grafana exports no grafanaApply — it predates chant #2948",
|
|
466
|
+
);
|
|
467
|
+
}
|
|
468
|
+
if (typeof toApplyResult !== "function") {
|
|
469
|
+
throw new Error(
|
|
470
|
+
"the installed @intentius/chant-lexicon-grafana exports no toApplyResult — it predates chant #2948",
|
|
471
|
+
);
|
|
472
|
+
}
|
|
473
|
+
return async (args, signal) => toApplyResult(await grafanaApply(args, signal));
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Load the sql lexicon's `clickhouseApply` (#3208). Same variable-specifier
|
|
478
|
+
* trick as {@link loadK8sApplier}, for the same reason.
|
|
479
|
+
*/
|
|
480
|
+
async function loadClickHouseApplier(): Promise<ClickHouseApplier> {
|
|
481
|
+
const spec = "@intentius/chant-lexicon-sql/op/activities";
|
|
482
|
+
type SqlModule = {
|
|
483
|
+
clickhouseApply?: (args: Parameters<ClickHouseApplier>[0], signal?: AbortSignal) => Promise<unknown>;
|
|
484
|
+
toApplyResult?: (result: unknown) => ApplyResult;
|
|
485
|
+
};
|
|
486
|
+
let mod: SqlModule;
|
|
487
|
+
try {
|
|
488
|
+
mod = (await importLexiconPackage(spec)) as SqlModule;
|
|
489
|
+
} catch (err) {
|
|
490
|
+
throw new Error(
|
|
491
|
+
`apply target "clickhouse" needs @intentius/chant-lexicon-sql, which could not be loaded ` +
|
|
492
|
+
`(${err instanceof Error ? err.message : String(err)}). ClickHouse applies go through the sql ` +
|
|
493
|
+
`lexicon's applier (chant #3208); install the sql lexicon and list it in chant.config.ts.`,
|
|
494
|
+
);
|
|
495
|
+
}
|
|
496
|
+
const { clickhouseApply, toApplyResult } = mod;
|
|
497
|
+
if (typeof clickhouseApply !== "function") {
|
|
498
|
+
throw new Error("the installed @intentius/chant-lexicon-sql exports no clickhouseApply — it predates chant #3208");
|
|
499
|
+
}
|
|
500
|
+
if (typeof toApplyResult !== "function") {
|
|
501
|
+
throw new Error("the installed @intentius/chant-lexicon-sql exports no toApplyResult — it predates chant #3208");
|
|
502
|
+
}
|
|
503
|
+
return async (args, signal) => toApplyResult(await clickhouseApply(args, signal));
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
/**
|
|
507
|
+
* Load the sql lexicon's `postgresApply` (#3280). Same variable-specifier
|
|
508
|
+
* trick as {@link loadK8sApplier}, for the same reason.
|
|
509
|
+
*/
|
|
510
|
+
async function loadPostgresApplier(): Promise<PostgresApplier> {
|
|
511
|
+
const spec = "@intentius/chant-lexicon-sql/op/activities";
|
|
512
|
+
type SqlModule = {
|
|
513
|
+
postgresApply?: (args: Parameters<PostgresApplier>[0], signal?: AbortSignal) => Promise<unknown>;
|
|
514
|
+
toApplyResult?: (result: unknown) => ApplyResult;
|
|
515
|
+
};
|
|
516
|
+
let mod: SqlModule;
|
|
517
|
+
try {
|
|
518
|
+
mod = (await importLexiconPackage(spec)) as SqlModule;
|
|
519
|
+
} catch (err) {
|
|
520
|
+
throw new Error(
|
|
521
|
+
`apply target "postgres" needs @intentius/chant-lexicon-sql, which could not be loaded ` +
|
|
522
|
+
`(${err instanceof Error ? err.message : String(err)}). Postgres applies go through the sql ` +
|
|
523
|
+
`lexicon's applier (chant #3280); install the sql lexicon and list it in chant.config.ts.`,
|
|
524
|
+
);
|
|
525
|
+
}
|
|
526
|
+
const { postgresApply, toApplyResult } = mod;
|
|
527
|
+
if (typeof postgresApply !== "function") {
|
|
528
|
+
throw new Error("the installed @intentius/chant-lexicon-sql exports no postgresApply — it predates chant #3280");
|
|
529
|
+
}
|
|
530
|
+
if (typeof toApplyResult !== "function") {
|
|
531
|
+
throw new Error("the installed @intentius/chant-lexicon-sql exports no toApplyResult — it predates chant #3208");
|
|
532
|
+
}
|
|
533
|
+
return async (args, signal) => toApplyResult(await postgresApply(args, signal));
|
|
534
|
+
}
|
|
535
|
+
|
|
366
536
|
/**
|
|
367
537
|
* Load the aws lexicon's `awsApply` (#1449). Same variable-specifier trick as
|
|
368
538
|
* {@link loadK8sApplier}, for the same reason.
|
|
@@ -418,8 +588,11 @@ async function loadAwsRollback(): Promise<AwsRollback> {
|
|
|
418
588
|
* manifests), so `dist`; kustomize's "output" is the kustomization DIRECTORY
|
|
419
589
|
* the render reads. The file targets take the file their lexicon's build
|
|
420
590
|
* conventionally emits: `template.json` for CloudFormation/ARM, `dist/gcp.yaml`
|
|
421
|
-
* (the CNRM manifest) for gcp, `dist/fly.json` (the serialized plan) for fly
|
|
422
|
-
*
|
|
591
|
+
* (the CNRM manifest) for gcp, `dist/fly.json` (the serialized plan) for fly,
|
|
592
|
+
* `dist/grafana.json` (the index the grafana serializer writes, with the
|
|
593
|
+
* dashboard files beside it) for grafana, `dist/schema.json` (the sql
|
|
594
|
+
* lexicon's build output) for clickhouse and postgres. Pure — exported for
|
|
595
|
+
* testing.
|
|
423
596
|
*/
|
|
424
597
|
export function defaultOutput(target: ApplyTarget): string {
|
|
425
598
|
switch (target) {
|
|
@@ -430,6 +603,11 @@ export function defaultOutput(target: ApplyTarget): string {
|
|
|
430
603
|
return "dist/gcp.yaml";
|
|
431
604
|
case "fly":
|
|
432
605
|
return "dist/fly.json";
|
|
606
|
+
case "grafana":
|
|
607
|
+
return "dist/grafana.json";
|
|
608
|
+
case "clickhouse":
|
|
609
|
+
case "postgres":
|
|
610
|
+
return "dist/schema.json";
|
|
433
611
|
default:
|
|
434
612
|
return "template.json";
|
|
435
613
|
}
|
|
@@ -469,7 +647,9 @@ function collapseEnvelope(envelope: ApplyResult, label: string): NativeApplyResu
|
|
|
469
647
|
* Apply declared source to the cloud via the target's native mechanism.
|
|
470
648
|
* Deletes (when enabled) ride that mechanism's own delete path — marker-scoped
|
|
471
649
|
* on `kubectl`, tag-scoped on `arm`, label-scoped on `gcp`, marker- and
|
|
472
|
-
* app-scoped on `fly`,
|
|
650
|
+
* app-scoped on `fly`, label-scoped on `grafana`, comment-marker-scoped on
|
|
651
|
+
* `clickhouse` and `postgres`, and stack-scoped on
|
|
652
|
+
* `cloudformation`, where the deploy
|
|
473
653
|
* itself removes resources dropped from the template and `deleteMode` changes
|
|
474
654
|
* nothing: a resource CFN did not create is not in the stack. See
|
|
475
655
|
* {@link DeleteMode}.
|
|
@@ -477,7 +657,7 @@ function collapseEnvelope(envelope: ApplyResult, label: string): NativeApplyResu
|
|
|
477
657
|
* The appliers are injectable so this dispatcher can be tested without the
|
|
478
658
|
* product lexicons present; production resolves them through
|
|
479
659
|
* {@link loadK8sApplier} / {@link loadAzureApplier} / {@link loadAwsApplier} /
|
|
480
|
-
* {@link loadGcpApplier} / {@link loadFlyApplier}.
|
|
660
|
+
* {@link loadGcpApplier} / {@link loadFlyApplier} / {@link loadGrafanaApplier}.
|
|
481
661
|
*/
|
|
482
662
|
export async function nativeApply(
|
|
483
663
|
args: NativeApplyArgs,
|
|
@@ -488,6 +668,9 @@ export async function nativeApply(
|
|
|
488
668
|
awsApplier?: AwsApplier,
|
|
489
669
|
gcpApplier?: GcpApplier,
|
|
490
670
|
flyApplier?: FlyApplier,
|
|
671
|
+
grafanaApplier?: GrafanaApplier,
|
|
672
|
+
clickhouseApplier?: ClickHouseApplier,
|
|
673
|
+
postgresApplier?: PostgresApplier,
|
|
491
674
|
): Promise<NativeApplyResult> {
|
|
492
675
|
const output = args.output ?? defaultOutput(args.target);
|
|
493
676
|
const deleteMode = args.deleteMode ?? "never";
|
|
@@ -568,6 +751,45 @@ export async function nativeApply(
|
|
|
568
751
|
return collapseEnvelope(envelope, args.env);
|
|
569
752
|
}
|
|
570
753
|
|
|
754
|
+
if (args.target === "grafana") {
|
|
755
|
+
// grafana (#3011): the grafana lexicon's API applier. Unlike gcp and fly,
|
|
756
|
+
// env is not just a label here: it selects `grafana.profiles.<env>`, the
|
|
757
|
+
// Grafana observe and export already read. The ownership marker comes from
|
|
758
|
+
// the project's chant.config.ts inside grafanaApply.
|
|
759
|
+
const apply = grafanaApplier ?? (await loadGrafanaApplier());
|
|
760
|
+
const envelope = await apply(
|
|
761
|
+
{ indexPath: output, environment: args.env, prune: deleteMode !== "never" },
|
|
762
|
+
signal,
|
|
763
|
+
);
|
|
764
|
+
// No binding or a refused token rides the envelope as NOT-ATTEMPTED for
|
|
765
|
+
// every resource, as do library panels and anything else prune could
|
|
766
|
+
// not consider.
|
|
767
|
+
return collapseEnvelope(envelope, args.env);
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
if (args.target === "clickhouse") {
|
|
771
|
+
// clickhouse (#3208): the sql lexicon's applier. env selects
|
|
772
|
+
// `sql.profiles.<env>`, the server observe and import read; the marker
|
|
773
|
+
// comes from the project's chant.config.ts inside clickhouseApply.
|
|
774
|
+
const apply = clickhouseApplier ?? (await loadClickHouseApplier());
|
|
775
|
+
const envelope = await apply({ buildPath: output, environment: args.env, prune: deleteMode !== "never" }, signal);
|
|
776
|
+
// A refused rebuild and a column drop an additive apply withholds ride the
|
|
777
|
+
// envelope as NOT-ATTEMPTED, so an Op can gate on them.
|
|
778
|
+
return collapseEnvelope(envelope, args.env);
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
if (args.target === "postgres") {
|
|
782
|
+
// postgres (#3280): the sql lexicon's applier. env selects
|
|
783
|
+
// `sql.profiles.<env>`; the marker and the lock and statement timeouts
|
|
784
|
+
// come from the project's chant.config.ts inside postgresApply.
|
|
785
|
+
const apply = postgresApplier ?? (await loadPostgresApplier());
|
|
786
|
+
const envelope = await apply({ buildPath: output, environment: args.env, prune: deleteMode !== "never" }, signal);
|
|
787
|
+
// A refused expand-and-contract change, a column drop an additive apply
|
|
788
|
+
// withholds, and the objects of a rolled-back transaction ride the
|
|
789
|
+
// envelope as NOT-ATTEMPTED, so an Op can gate on them.
|
|
790
|
+
return collapseEnvelope(envelope, args.env);
|
|
791
|
+
}
|
|
792
|
+
|
|
571
793
|
// cloudformation (#1449): the aws lexicon's native applier. env is the stack
|
|
572
794
|
// name and output the template path; endpoint resolution (#1694) and
|
|
573
795
|
// capability derivation (#980) are awsApply's own, so nothing else is passed.
|
|
@@ -18,23 +18,37 @@ import type { UpgradeCheckResult } from "../../codegen/pinned-upgrade";
|
|
|
18
18
|
import type { RollingUpgradeResult } from "../../codegen/rolling-upgrade";
|
|
19
19
|
import { tmpdir } from "node:os";
|
|
20
20
|
import { join } from "node:path";
|
|
21
|
-
import { writeFileSync, readFileSync } from "node:fs";
|
|
21
|
+
import { writeFileSync, readFileSync, mkdirSync } from "node:fs";
|
|
22
22
|
|
|
23
23
|
// ── Classification ────────────────────────────────────────────────────
|
|
24
24
|
|
|
25
25
|
describe("pinned vs rolling classification", () => {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
const pin = {
|
|
27
|
+
file: "src/pin.ts",
|
|
28
|
+
pattern: /V = "(.+)"/,
|
|
29
|
+
replace: (v: string) => `V = "${v}"`,
|
|
30
|
+
upstream: { owner: "o", repo: "r", kind: "releases" as const },
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
test("pinned lexicons are any whose plugin declares upstreamPin", async () => {
|
|
34
|
+
const loadPin = vi.fn(async () => pin);
|
|
35
|
+
for (const l of ["k8s", "gcp", "docker", "gitlab", "sql", "k3s", "cedar"]) {
|
|
36
|
+
expect(await isPinned(l, "/x", loadPin)).toBe(true);
|
|
29
37
|
expect(isRolling(l)).toBe(false);
|
|
30
38
|
}
|
|
31
39
|
});
|
|
32
40
|
|
|
33
|
-
test("
|
|
41
|
+
test("a lexicon without a pin is not pinned", async () => {
|
|
42
|
+
expect(await isPinned("helm", "/x", async () => null)).toBe(false);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test("rolling lexicons", async () => {
|
|
46
|
+
const loadPin = vi.fn(async () => null);
|
|
34
47
|
for (const l of ["aws", "azure", "github"] as const) {
|
|
35
48
|
expect(isRolling(l)).toBe(true);
|
|
36
|
-
expect(isPinned(l)).toBe(false);
|
|
49
|
+
expect(await isPinned(l, "/x", loadPin)).toBe(false);
|
|
37
50
|
}
|
|
51
|
+
expect(loadPin).not.toHaveBeenCalled();
|
|
38
52
|
});
|
|
39
53
|
});
|
|
40
54
|
|
|
@@ -389,6 +403,86 @@ describe("lexiconUpgrade breakage handling", () => {
|
|
|
389
403
|
|
|
390
404
|
// ── out-of-scope rejection ────────────────────────────────────────────
|
|
391
405
|
|
|
406
|
+
describe("discovered pinned lexicons (#3266)", () => {
|
|
407
|
+
const pin = {
|
|
408
|
+
file: "src/pin.ts",
|
|
409
|
+
pattern: /V = "(.+)"/,
|
|
410
|
+
replace: (v: string) => `V = "${v}"`,
|
|
411
|
+
upstream: { owner: "o", repo: "r", kind: "releases" as const },
|
|
412
|
+
};
|
|
413
|
+
|
|
414
|
+
test("a lexicon with a declared pin reaches the pinned check and opens a PR", async () => {
|
|
415
|
+
const checkPinned: CheckPinnedFn = vi.fn(async () => pinnedResult());
|
|
416
|
+
const applyBump = vi.fn(async () => ({ filePath: "/x/src/pin.ts" }));
|
|
417
|
+
const { gh } = recordingGh();
|
|
418
|
+
const dir = join(tmpdir(), `chant-3266-${process.pid}`);
|
|
419
|
+
mkdirSync(dir, { recursive: true });
|
|
420
|
+
writeFileSync(join(dir, "package.json"), JSON.stringify({ version: "0.1.0" }));
|
|
421
|
+
const r = await lexiconUpgrade({
|
|
422
|
+
lexicon: "k3s",
|
|
423
|
+
lexiconDir: dir,
|
|
424
|
+
mode: "pull-request",
|
|
425
|
+
_loadPin: async () => pin,
|
|
426
|
+
_checkPinned: checkPinned,
|
|
427
|
+
_applyBump: applyBump,
|
|
428
|
+
_bumpPackageVersion: vi.fn(),
|
|
429
|
+
_gh: gh,
|
|
430
|
+
});
|
|
431
|
+
expect(checkPinned).toHaveBeenCalledOnce();
|
|
432
|
+
expect(applyBump).toHaveBeenCalledWith("k3s", dir, "v1.33.0");
|
|
433
|
+
expect(r.hasUpgrade).toBe(true);
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
test("a lexicon with no pin and not rolling is rejected", async () => {
|
|
437
|
+
await expect(
|
|
438
|
+
lexiconUpgrade({ lexicon: "helm", mode: "report", _loadPin: async () => null }),
|
|
439
|
+
).rejects.toThrow(/not supported/);
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
test("a discovered pin reaches the real check when none is injected", async () => {
|
|
443
|
+
const loadPin = vi.fn(async () => pin);
|
|
444
|
+
// The real checkPinnedUpgrade loads the pin itself; an empty dir has no
|
|
445
|
+
// plugin, so it reports the fetch error rather than throwing "not supported".
|
|
446
|
+
const r = await lexiconUpgrade({
|
|
447
|
+
lexicon: "sql",
|
|
448
|
+
lexiconDir: join(tmpdir(), "chant-3266-none"),
|
|
449
|
+
mode: "report",
|
|
450
|
+
_loadPin: loadPin,
|
|
451
|
+
});
|
|
452
|
+
expect(loadPin).toHaveBeenCalledOnce();
|
|
453
|
+
expect(r.validationOk).toBe(false);
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
test("an alsoMoves pin is report-only: newer version and manual step, no bump, no git", async () => {
|
|
457
|
+
const manual = pinnedResult({
|
|
458
|
+
validation: null,
|
|
459
|
+
from: "25.8.1.1-lts",
|
|
460
|
+
to: "26.3.1.1-lts",
|
|
461
|
+
manualPin: { file: "src/spec/pin.ts", instructions: "move CLICKHOUSE_IMAGE_DIGEST too" },
|
|
462
|
+
});
|
|
463
|
+
const applyBump = vi.fn();
|
|
464
|
+
const { gh, calls } = recordingGh();
|
|
465
|
+
for (const mode of ["report", "issue", "pull-request"] as const) {
|
|
466
|
+
const r = await lexiconUpgrade({
|
|
467
|
+
lexicon: "sql",
|
|
468
|
+
mode,
|
|
469
|
+
_checkPinned: vi.fn(async () => manual),
|
|
470
|
+
_applyBump: applyBump,
|
|
471
|
+
_gh: gh,
|
|
472
|
+
});
|
|
473
|
+
expect(r.hasUpgrade).toBe(true);
|
|
474
|
+
expect(r.mode).toBe("report");
|
|
475
|
+
expect(r.prUrl).toBeUndefined();
|
|
476
|
+
expect(r.issueUrl).toBeUndefined();
|
|
477
|
+
expect(r.summary).toContain("26.3.1.1-lts");
|
|
478
|
+
expect(r.summary).toContain("move CLICKHOUSE_IMAGE_DIGEST too");
|
|
479
|
+
expect(r.summary).toContain("src/spec/pin.ts");
|
|
480
|
+
}
|
|
481
|
+
expect(applyBump).not.toHaveBeenCalled();
|
|
482
|
+
expect(calls).toHaveLength(0);
|
|
483
|
+
});
|
|
484
|
+
});
|
|
485
|
+
|
|
392
486
|
describe("out-of-scope lexicons", () => {
|
|
393
487
|
test("helm/forgejo throw", async () => {
|
|
394
488
|
for (const l of ["helm", "forgejo"]) {
|
|
@@ -585,3 +679,63 @@ describe("lexiconUpgrade pull-request mode: package.json version bump", () => {
|
|
|
585
679
|
}
|
|
586
680
|
});
|
|
587
681
|
});
|
|
682
|
+
|
|
683
|
+
describe("a lexicon with several pins (#3288)", () => {
|
|
684
|
+
const manual = (pin: string, from: string, to: string): UpgradeCheckResult =>
|
|
685
|
+
pinnedResult({ pin, validation: null, from, to, manualPin: { file: "src/spec/postgres-pin.ts", instructions: `move the ${pin} digest too` } });
|
|
686
|
+
const current = (pin: string, v: string): UpgradeCheckResult => pinnedResult({ pin, validation: null, hasUpgrade: false, from: v, to: v });
|
|
687
|
+
|
|
688
|
+
test("every pin is reported; manual pins stay report-only in every mode", async () => {
|
|
689
|
+
const results = [current("clickhouse", "26.8.15.10"), manual("postgres-17", "17.11", "17.12"), manual("postgres-14", "14.24", "14.25")];
|
|
690
|
+
const applyBump = vi.fn();
|
|
691
|
+
const { gh, calls } = recordingGh();
|
|
692
|
+
for (const mode of ["report", "issue", "pull-request"] as const) {
|
|
693
|
+
const r = await lexiconUpgrade({ lexicon: "sql", mode, _checkPinned: vi.fn(async () => results), _applyBump: applyBump, _gh: gh });
|
|
694
|
+
expect(r.hasUpgrade).toBe(true);
|
|
695
|
+
expect(r.mode).toBe("report");
|
|
696
|
+
expect(r.summary).toContain("## Lexicon upgrade: sql (clickhouse)");
|
|
697
|
+
expect(r.summary).toContain("## Lexicon upgrade: sql (postgres-17)");
|
|
698
|
+
expect(r.summary).toContain("move the postgres-17 digest too");
|
|
699
|
+
expect(r.summary).toContain("move the postgres-14 digest too");
|
|
700
|
+
}
|
|
701
|
+
expect(applyBump).not.toHaveBeenCalled();
|
|
702
|
+
expect(calls).toHaveLength(0);
|
|
703
|
+
});
|
|
704
|
+
|
|
705
|
+
test("no pin has an upgrade: nothing to do", async () => {
|
|
706
|
+
const r = await lexiconUpgrade({
|
|
707
|
+
lexicon: "sql",
|
|
708
|
+
_checkPinned: vi.fn(async () => [current("clickhouse", "1.0"), current("postgres-18", "18.6")]),
|
|
709
|
+
});
|
|
710
|
+
expect(r.hasUpgrade).toBe(false);
|
|
711
|
+
expect(r.validationOk).toBe(true);
|
|
712
|
+
});
|
|
713
|
+
|
|
714
|
+
test("the pin label is forwarded to the check", async () => {
|
|
715
|
+
const check = vi.fn(async () => [current("postgres-16", "16.15")]);
|
|
716
|
+
await lexiconUpgrade({ lexicon: "sql", pin: "postgres-16", _checkPinned: check });
|
|
717
|
+
expect(check).toHaveBeenCalledWith(expect.objectContaining({ lexicon: "sql", pin: "postgres-16" }));
|
|
718
|
+
});
|
|
719
|
+
|
|
720
|
+
test("a rewritable pin leads: the PR branch, title and bump name the pin", async () => {
|
|
721
|
+
const results = [manual("clickhouse", "1.0", "2.0"), pinnedResult({ pin: "postgres-17", from: "17.11", to: "17.12" })];
|
|
722
|
+
const applyBump = vi.fn(async () => ({ filePath: "/x/pin.ts" }));
|
|
723
|
+
const { gh, calls } = recordingGh();
|
|
724
|
+
const dir = join(tmpdir(), `chant-3288-${process.pid}`);
|
|
725
|
+
mkdirSync(dir, { recursive: true });
|
|
726
|
+
writeFileSync(join(dir, "package.json"), JSON.stringify({ version: "0.1.0" }));
|
|
727
|
+
await lexiconUpgrade({
|
|
728
|
+
lexicon: "sql",
|
|
729
|
+
mode: "pull-request",
|
|
730
|
+
lexiconDir: dir,
|
|
731
|
+
_checkPinned: vi.fn(async () => results),
|
|
732
|
+
_applyBump: applyBump,
|
|
733
|
+
_bumpPackageVersion: vi.fn(() => "/x/package.json"),
|
|
734
|
+
_gh: gh,
|
|
735
|
+
});
|
|
736
|
+
expect(applyBump).toHaveBeenCalledWith("sql", dir, "17.12", "postgres-17");
|
|
737
|
+
expect(calls.some((c) => c.includes("lexicon-upgrade/sql-postgres-17"))).toBe(true);
|
|
738
|
+
expect(upgradeBranchName("sql", "postgres-17")).toBe("lexicon-upgrade/sql-postgres-17");
|
|
739
|
+
expect(upgradePrTitle("sql", "17.11", "17.12", "postgres-17")).toBe("feat(sql): upgrade postgres-17 17.11 to 17.12");
|
|
740
|
+
});
|
|
741
|
+
});
|