@intentius/chant 0.124.28 → 0.124.30
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/build-params.d.ts +34 -1
- package/dist/build-params.d.ts.map +1 -1
- package/dist/build-params.js +31 -1
- package/dist/change-set-graph.d.ts +8 -1
- package/dist/change-set-graph.d.ts.map +1 -1
- package/dist/change-set-graph.js +4 -2
- package/dist/change-set.d.ts +10 -0
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +4 -3
- package/dist/cli/build-params-cli.d.ts +7 -1
- package/dist/cli/build-params-cli.d.ts.map +1 -1
- package/dist/cli/build-params-cli.js +17 -8
- package/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/commands/build.js +6 -3
- package/dist/cli/handlers/approve.d.ts.map +1 -1
- package/dist/cli/handlers/approve.js +45 -0
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/build.js +18 -4
- package/dist/cli/handlers/fan-out.d.ts +9 -0
- package/dist/cli/handlers/fan-out.d.ts.map +1 -1
- package/dist/cli/handlers/fan-out.js +67 -8
- package/dist/cli/handlers/lifecycle-gc.d.ts +19 -0
- package/dist/cli/handlers/lifecycle-gc.d.ts.map +1 -0
- package/dist/cli/handlers/lifecycle-gc.js +143 -0
- package/dist/cli/handlers/pr.d.ts +11 -3
- package/dist/cli/handlers/pr.d.ts.map +1 -1
- package/dist/cli/handlers/pr.js +134 -26
- package/dist/cli/handlers/promote.d.ts +7 -0
- package/dist/cli/handlers/promote.d.ts.map +1 -1
- package/dist/cli/handlers/promote.js +210 -33
- package/dist/cli/handlers/release.d.ts +62 -5
- package/dist/cli/handlers/release.d.ts.map +1 -1
- package/dist/cli/handlers/release.js +414 -28
- package/dist/cli/handlers/run.d.ts +11 -1
- package/dist/cli/handlers/run.d.ts.map +1 -1
- package/dist/cli/handlers/run.js +67 -6
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +91 -10
- package/dist/cli/parse-args.d.ts.map +1 -1
- package/dist/cli/parse-args.js +73 -2
- package/dist/cli/registry.d.ts +32 -4
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/cli/run-events.d.ts +3 -2
- package/dist/cli/run-events.d.ts.map +1 -1
- package/dist/cli/run-events.js +5 -3
- package/dist/components/auto-release.d.ts +2 -0
- package/dist/components/auto-release.d.ts.map +1 -1
- package/dist/components/auto-release.js +1 -0
- package/dist/components/capability.d.ts +9 -0
- package/dist/components/capability.d.ts.map +1 -1
- package/dist/components/driver.d.ts +8 -0
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/driver.js +35 -0
- package/dist/components/fan-out-inputs.d.ts +69 -0
- package/dist/components/fan-out-inputs.d.ts.map +1 -0
- package/dist/components/fan-out-inputs.js +169 -0
- package/dist/components/fan-out-record.d.ts +13 -0
- package/dist/components/fan-out-record.d.ts.map +1 -1
- package/dist/components/fan-out-record.js +16 -0
- package/dist/components/fan-out-run.d.ts.map +1 -1
- package/dist/components/fan-out-run.js +50 -0
- package/dist/components/fan-out.d.ts +4 -0
- package/dist/components/fan-out.d.ts.map +1 -1
- package/dist/components/pr-pipeline.d.ts +49 -0
- package/dist/components/pr-pipeline.d.ts.map +1 -1
- package/dist/components/pr-pipeline.js +38 -4
- package/dist/components/pr-run.d.ts +20 -2
- package/dist/components/pr-run.d.ts.map +1 -1
- package/dist/components/pr-run.js +26 -13
- package/dist/components/promote.d.ts +23 -0
- package/dist/components/promote.d.ts.map +1 -1
- package/dist/components/promote.js +60 -2
- package/dist/components/release-compile.d.ts +9 -0
- package/dist/components/release-compile.d.ts.map +1 -1
- package/dist/components/release-compile.js +9 -3
- package/dist/components/release-gate.d.ts +11 -1
- package/dist/components/release-gate.d.ts.map +1 -1
- package/dist/components/release-gate.js +10 -4
- package/dist/components/wave-plan.d.ts +16 -0
- package/dist/components/wave-plan.d.ts.map +1 -1
- package/dist/components/wave-plan.js +36 -2
- package/dist/config.d.ts +38 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -0
- package/dist/flag-params.d.ts +54 -0
- package/dist/flag-params.d.ts.map +1 -0
- package/dist/flag-params.js +130 -0
- package/dist/lifecycle/__fixtures__/publish-fakes.d.ts +120 -0
- package/dist/lifecycle/__fixtures__/publish-fakes.d.ts.map +1 -0
- package/dist/lifecycle/__fixtures__/publish-fakes.js +304 -0
- package/dist/lifecycle/change-set-store.d.ts +2 -1
- package/dist/lifecycle/change-set-store.d.ts.map +1 -1
- package/dist/lifecycle/change-set-store.js +2 -1
- package/dist/lifecycle/delivery-metrics.d.ts +139 -0
- package/dist/lifecycle/delivery-metrics.d.ts.map +1 -0
- package/dist/lifecycle/delivery-metrics.js +145 -0
- package/dist/lifecycle/deploy-outcome.d.ts +81 -0
- package/dist/lifecycle/deploy-outcome.d.ts.map +1 -0
- package/dist/lifecycle/deploy-outcome.js +101 -0
- package/dist/lifecycle/gate-change-set.d.ts +10 -1
- package/dist/lifecycle/gate-change-set.d.ts.map +1 -1
- package/dist/lifecycle/gate-change-set.js +35 -3
- package/dist/lifecycle/gate-ledger.d.ts +2 -3
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
- package/dist/lifecycle/git.d.ts +30 -1
- package/dist/lifecycle/git.d.ts.map +1 -1
- package/dist/lifecycle/git.js +31 -5
- 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/mixed-environment.d.ts +95 -0
- package/dist/lifecycle/mixed-environment.d.ts.map +1 -0
- package/dist/lifecycle/mixed-environment.js +154 -0
- package/dist/lifecycle/publish-attachments.d.ts +79 -0
- package/dist/lifecycle/publish-attachments.d.ts.map +1 -0
- package/dist/lifecycle/publish-attachments.js +179 -0
- package/dist/lifecycle/publish-credentials.d.ts +37 -0
- package/dist/lifecycle/publish-credentials.d.ts.map +1 -0
- package/dist/lifecycle/publish-credentials.js +69 -0
- package/dist/lifecycle/publish-declaration.d.ts +97 -0
- package/dist/lifecycle/publish-declaration.d.ts.map +1 -0
- package/dist/lifecycle/publish-declaration.js +83 -0
- package/dist/lifecycle/publish-forge.d.ts +53 -0
- package/dist/lifecycle/publish-forge.d.ts.map +1 -0
- package/dist/lifecycle/publish-forge.js +298 -0
- package/dist/lifecycle/publish-npm.d.ts +61 -0
- package/dist/lifecycle/publish-npm.d.ts.map +1 -0
- package/dist/lifecycle/publish-npm.js +242 -0
- package/dist/lifecycle/publish-oci.d.ts +64 -0
- package/dist/lifecycle/publish-oci.d.ts.map +1 -0
- package/dist/lifecycle/publish-oci.js +383 -0
- package/dist/lifecycle/publish-record.d.ts +66 -0
- package/dist/lifecycle/publish-record.d.ts.map +1 -0
- package/dist/lifecycle/publish-record.js +84 -0
- package/dist/lifecycle/publish-targets.d.ts +45 -0
- package/dist/lifecycle/publish-targets.d.ts.map +1 -0
- package/dist/lifecycle/publish-targets.js +85 -0
- package/dist/lifecycle/release-cut.d.ts +48 -1
- package/dist/lifecycle/release-cut.d.ts.map +1 -1
- package/dist/lifecycle/release-cut.js +116 -23
- package/dist/lifecycle/release-join.d.ts +95 -0
- package/dist/lifecycle/release-join.d.ts.map +1 -0
- package/dist/lifecycle/release-join.js +139 -0
- package/dist/lifecycle/release-ledger.d.ts +8 -3
- package/dist/lifecycle/release-ledger.d.ts.map +1 -1
- package/dist/lifecycle/release-ledger.js +2 -0
- package/dist/lifecycle/release-publish.d.ts +312 -0
- package/dist/lifecycle/release-publish.d.ts.map +1 -0
- package/dist/lifecycle/release-publish.js +335 -0
- package/dist/lifecycle/release-revocation.d.ts +80 -0
- package/dist/lifecycle/release-revocation.d.ts.map +1 -0
- package/dist/lifecycle/release-revocation.js +123 -0
- package/dist/lifecycle/release-store.d.ts +12 -2
- package/dist/lifecycle/release-store.d.ts.map +1 -1
- package/dist/lifecycle/release-store.js +4 -2
- package/dist/lifecycle/release-verify.d.ts +61 -0
- package/dist/lifecycle/release-verify.d.ts.map +1 -0
- package/dist/lifecycle/release-verify.js +92 -0
- package/dist/lifecycle/release-workstation.d.ts +91 -0
- package/dist/lifecycle/release-workstation.d.ts.map +1 -0
- package/dist/lifecycle/release-workstation.js +180 -0
- package/dist/lifecycle/retention-policy.d.ts +45 -0
- package/dist/lifecycle/retention-policy.d.ts.map +1 -0
- package/dist/lifecycle/retention-policy.js +43 -0
- package/dist/lifecycle/retention.d.ts +185 -0
- package/dist/lifecycle/retention.d.ts.map +1 -0
- package/dist/lifecycle/retention.js +400 -0
- package/dist/lifecycle/run-ledger.d.ts +1 -1
- package/dist/lifecycle/run-ledger.d.ts.map +1 -1
- package/dist/lifecycle/run-ledger.js +9 -0
- package/dist/op/activities/activity-contracts.d.ts +1 -0
- package/dist/op/activities/activity-contracts.d.ts.map +1 -1
- package/dist/op/activities/activity-contracts.js +1 -0
- package/dist/op/activities/shell.d.ts +6 -0
- package/dist/op/activities/shell.d.ts.map +1 -1
- package/dist/op/activities/shell.js +1 -1
- package/dist/op/local-executor.d.ts +23 -1
- package/dist/op/local-executor.d.ts.map +1 -1
- package/dist/op/local-executor.js +9 -3
- package/dist/op/runtime.d.ts +27 -0
- package/dist/op/runtime.d.ts.map +1 -1
- package/dist/op/runtime.js +20 -0
- package/dist/plan-summary.d.ts.map +1 -1
- package/dist/plan-summary.js +8 -2
- package/dist/pr-forge.d.ts +23 -0
- package/dist/pr-forge.d.ts.map +1 -1
- package/dist/pr-forge.js +44 -0
- package/dist/pr-loop.d.ts +17 -0
- package/dist/pr-loop.d.ts.map +1 -1
- package/dist/pr-loop.js +30 -4
- package/dist/pr-report-url.d.ts +82 -0
- package/dist/pr-report-url.d.ts.map +1 -0
- package/dist/pr-report-url.js +174 -0
- package/dist/provenance.d.ts +2 -2
- package/dist/provenance.d.ts.map +1 -1
- package/dist/run-event-store.d.ts +29 -2
- package/dist/run-event-store.d.ts.map +1 -1
- package/dist/run-event-store.js +50 -3
- package/dist/run-event-stream.d.ts +4 -3
- package/dist/run-event-stream.d.ts.map +1 -1
- package/dist/run-event-stream.js +7 -3
- package/dist/run-event.d.ts +34 -1
- package/dist/run-event.d.ts.map +1 -1
- package/dist/run-event.js +4 -0
- package/dist/wave-runtime.mjs +260 -229
- package/dist/workspace/__fixtures__/flag-workspace.d.ts +31 -0
- package/dist/workspace/__fixtures__/flag-workspace.d.ts.map +1 -0
- package/dist/workspace/__fixtures__/flag-workspace.js +114 -0
- package/dist/workspace/change-set.schema.json +5 -1
- package/dist/workspace/check.schema.json +4 -2
- package/dist/workspace/checks/records.d.ts +9 -1
- package/dist/workspace/checks/records.d.ts.map +1 -1
- package/dist/workspace/checks/records.js +35 -1
- package/dist/workspace/checks.d.ts +1 -0
- package/dist/workspace/checks.d.ts.map +1 -1
- package/dist/workspace/checks.js +2 -1
- package/dist/workspace/ci-green-forge.d.ts +2 -0
- package/dist/workspace/ci-green-forge.d.ts.map +1 -1
- package/dist/workspace/ci-green.d.ts +10 -0
- package/dist/workspace/ci-green.d.ts.map +1 -1
- package/dist/workspace/ci-green.js +14 -5
- package/dist/workspace/ci-run.d.ts +222 -0
- package/dist/workspace/ci-run.d.ts.map +1 -0
- package/dist/workspace/ci-run.js +464 -0
- package/dist/workspace/ci-serve.d.ts +214 -0
- package/dist/workspace/ci-serve.d.ts.map +1 -0
- package/dist/workspace/ci-serve.js +412 -0
- package/dist/workspace/declaration.d.ts +16 -0
- package/dist/workspace/declaration.d.ts.map +1 -1
- package/dist/workspace/declaration.js +26 -0
- package/dist/workspace/declaration.schema.json +64 -0
- package/dist/workspace/declared-kinds.d.ts +16 -0
- package/dist/workspace/declared-kinds.d.ts.map +1 -1
- package/dist/workspace/declared-kinds.js +25 -0
- package/dist/workspace/delivery-metrics.d.ts +91 -0
- package/dist/workspace/delivery-metrics.d.ts.map +1 -0
- package/dist/workspace/delivery-metrics.js +217 -0
- package/dist/workspace/delivery-metrics.schema.json +519 -0
- package/dist/workspace/flags-read.d.ts +37 -0
- package/dist/workspace/flags-read.d.ts.map +1 -0
- package/dist/workspace/flags-read.js +103 -0
- package/dist/workspace/flags.d.ts +100 -0
- package/dist/workspace/flags.d.ts.map +1 -0
- package/dist/workspace/flags.js +98 -0
- package/dist/workspace/graph-cli.js +1 -1
- package/dist/workspace/intent-cli.d.ts +11 -2
- package/dist/workspace/intent-cli.d.ts.map +1 -1
- package/dist/workspace/intent-cli.js +54 -5
- package/dist/workspace/intent-trace.d.ts +219 -0
- package/dist/workspace/intent-trace.d.ts.map +1 -0
- package/dist/workspace/intent-trace.js +314 -0
- package/dist/workspace/intent.d.ts +30 -6
- package/dist/workspace/intent.d.ts.map +1 -1
- package/dist/workspace/intent.js +141 -21
- package/dist/workspace/intent.schema.json +702 -6
- package/dist/workspace/overlap.d.ts +146 -0
- package/dist/workspace/overlap.d.ts.map +1 -0
- package/dist/workspace/overlap.js +276 -0
- package/dist/workspace/pr-report.schema.json +5 -0
- package/dist/workspace/reason-codes.d.ts +2 -0
- package/dist/workspace/reason-codes.d.ts.map +1 -1
- package/dist/workspace/reason-codes.js +3 -0
- package/dist/workspace/records.d.ts +15 -2
- package/dist/workspace/records.d.ts.map +1 -1
- package/dist/workspace/records.js +32 -0
- package/dist/workspace/records.schema.json +21 -2
- package/dist/workspace/reference-kinds/flag/flag.kind.mjs +32 -0
- package/dist/workspace/reference-kinds/flag/flag.schema.json +53 -0
- package/dist/workspace/releases.d.ts +9 -0
- package/dist/workspace/releases.d.ts.map +1 -1
- package/dist/workspace/releases.js +9 -0
- package/dist/workspace/releases.schema.json +123 -1
- package/dist/workspace/run-event.schema.json +24 -6
- package/dist/workspace/status-gates.d.ts +8 -0
- package/dist/workspace/status-gates.d.ts.map +1 -1
- package/dist/workspace/status-stewards.d.ts +2 -0
- package/dist/workspace/status-stewards.d.ts.map +1 -1
- package/dist/workspace/status-stewards.js +1 -0
- package/dist/workspace/status.d.ts +78 -0
- package/dist/workspace/status.d.ts.map +1 -1
- package/dist/workspace/status.js +170 -3
- package/dist/workspace/status.schema.json +210 -2
- package/dist/workspace/wip.d.ts.map +1 -1
- package/dist/workspace/wip.js +11 -3
- package/package.json +1 -1
- package/src/build-params.test.ts +46 -0
- package/src/build-params.ts +55 -1
- package/src/change-set-graph.ts +10 -2
- package/src/change-set.ts +14 -3
- package/src/cli/build-params-cli.ts +22 -9
- package/src/cli/commands/build.ts +6 -3
- package/src/cli/handlers/approve-release.test.ts +5 -1
- package/src/cli/handlers/approve-revoked.test.ts +155 -0
- package/src/cli/handlers/approve.ts +47 -0
- package/src/cli/handlers/build.test.ts +30 -0
- package/src/cli/handlers/build.ts +20 -4
- package/src/cli/handlers/fan-out.test.ts +262 -1
- package/src/cli/handlers/fan-out.ts +72 -8
- package/src/cli/handlers/intent-trace.e2e.test.ts +201 -0
- package/src/cli/handlers/lifecycle-gc.test.ts +126 -0
- package/src/cli/handlers/lifecycle-gc.ts +146 -0
- package/src/cli/handlers/pr.test.ts +148 -1
- package/src/cli/handlers/pr.ts +144 -28
- package/src/cli/handlers/promote.test.ts +280 -2
- package/src/cli/handlers/promote.ts +210 -34
- package/src/cli/handlers/release-implicit.e2e.test.ts +12 -4
- package/src/cli/handlers/release-join.e2e.test.ts +185 -0
- package/src/cli/handlers/release-publish-targets.e2e.test.ts +295 -0
- package/src/cli/handlers/release-verify.e2e.test.ts +117 -0
- package/src/cli/handlers/release-workstation-ci.e2e.test.ts +135 -0
- package/src/cli/handlers/release.e2e.test.ts +146 -32
- package/src/cli/handlers/release.ts +415 -28
- package/src/cli/handlers/run-auto-release.test.ts +9 -0
- package/src/cli/handlers/run-release.test.ts +55 -0
- package/src/cli/handlers/run.ts +69 -5
- package/src/cli/main.test.ts +1 -0
- package/src/cli/main.ts +91 -10
- package/src/cli/parse-args.ts +54 -2
- package/src/cli/registry.ts +32 -4
- package/src/cli/run-events.ts +5 -2
- package/src/components/auto-release.test.ts +9 -0
- package/src/components/auto-release.ts +3 -0
- package/src/components/capability.ts +9 -0
- package/src/components/driver.test.ts +24 -0
- package/src/components/driver.ts +36 -0
- package/src/components/fan-out-inputs.test.ts +85 -0
- package/src/components/fan-out-inputs.ts +192 -0
- package/src/components/fan-out-record.test.ts +10 -0
- package/src/components/fan-out-record.ts +19 -0
- package/src/components/fan-out-run.ts +48 -0
- package/src/components/fan-out.ts +4 -0
- package/src/components/pr-pipeline.ts +67 -4
- package/src/components/pr-run.test.ts +127 -0
- package/src/components/pr-run.ts +32 -12
- package/src/components/promote.ts +68 -2
- package/src/components/release-compile.ts +17 -3
- package/src/components/release-gate.ts +18 -4
- package/src/components/wave-plan.ts +45 -2
- package/src/config.ts +8 -0
- package/src/flag-params.test.ts +144 -0
- package/src/flag-params.ts +134 -0
- package/src/lifecycle/__fixtures__/publish-fakes.ts +351 -0
- package/src/lifecycle/change-set-store.ts +2 -1
- package/src/lifecycle/delivery-metrics.ts +263 -0
- package/src/lifecycle/deploy-outcome.ts +147 -0
- package/src/lifecycle/gate-change-set.ts +37 -6
- package/src/lifecycle/gate-ledger.ts +2 -2
- package/src/lifecycle/git.ts +61 -8
- package/src/lifecycle/index.ts +4 -0
- package/src/lifecycle/mixed-environment.test.ts +97 -0
- package/src/lifecycle/mixed-environment.ts +204 -0
- package/src/lifecycle/publish-attachments.ts +196 -0
- package/src/lifecycle/publish-credentials.ts +84 -0
- package/src/lifecycle/publish-declaration.ts +95 -0
- package/src/lifecycle/publish-forge.ts +325 -0
- package/src/lifecycle/publish-npm.ts +259 -0
- package/src/lifecycle/publish-oci.ts +396 -0
- package/src/lifecycle/publish-record.ts +113 -0
- package/src/lifecycle/publish-resume.test.ts +168 -0
- package/src/lifecycle/publish-targets.test.ts +494 -0
- package/src/lifecycle/publish-targets.ts +100 -0
- package/src/lifecycle/release-cut.test.ts +74 -2
- package/src/lifecycle/release-cut.ts +158 -22
- package/src/lifecycle/release-flag.test.ts +112 -0
- package/src/lifecycle/release-join.test.ts +68 -0
- package/src/lifecycle/release-join.ts +182 -0
- package/src/lifecycle/release-ledger.ts +9 -3
- package/src/lifecycle/release-publish.test.ts +225 -0
- package/src/lifecycle/release-publish.ts +568 -0
- package/src/lifecycle/release-revocation.ts +147 -0
- package/src/lifecycle/release-store.ts +15 -4
- package/src/lifecycle/release-verify.test.ts +110 -0
- package/src/lifecycle/release-verify.ts +120 -0
- package/src/lifecycle/release-workstation.test.ts +204 -0
- package/src/lifecycle/release-workstation.ts +216 -0
- package/src/lifecycle/retention-growth.e2e.test.ts +279 -0
- package/src/lifecycle/retention-policy.ts +63 -0
- package/src/lifecycle/retention.test.ts +363 -0
- package/src/lifecycle/retention.ts +508 -0
- package/src/lifecycle/run-ledger.ts +7 -1
- package/src/op/activities/activity-contracts.ts +1 -0
- package/src/op/activities/shell.ts +7 -1
- package/src/op/local-executor.ts +27 -4
- package/src/op/runtime.ts +42 -0
- package/src/plan-summary.test.ts +20 -0
- package/src/plan-summary.ts +8 -1
- package/src/pr-forge.test.ts +25 -0
- package/src/pr-forge.ts +62 -0
- package/src/pr-loop.test.ts +13 -1
- package/src/pr-loop.ts +41 -4
- package/src/pr-report-url.test.ts +131 -0
- package/src/pr-report-url.ts +209 -0
- package/src/provenance.ts +2 -2
- package/src/run-event-store.ts +63 -3
- package/src/run-event-stream.ts +8 -4
- package/src/run-event.ts +38 -1
- package/src/workspace/__fixtures__/flag-workspace.ts +132 -0
- package/src/workspace/__fixtures__/older-records/change-set-984534ea9.json +100 -0
- package/src/workspace/__fixtures__/older-records/older-records.json +326 -0
- package/src/workspace/change-set.schema.json +5 -1
- package/src/workspace/check.schema.json +4 -2
- package/src/workspace/checks/records.ts +35 -1
- package/src/workspace/checks.ts +2 -1
- package/src/workspace/ci-green-forge.ts +2 -0
- package/src/workspace/ci-green.ts +20 -5
- package/src/workspace/ci-run.test.ts +416 -0
- package/src/workspace/ci-run.ts +571 -0
- package/src/workspace/ci-serve.test.ts +268 -0
- package/src/workspace/ci-serve.ts +521 -0
- package/src/workspace/declaration.schema.json +64 -0
- package/src/workspace/declaration.test.ts +28 -0
- package/src/workspace/declaration.ts +38 -0
- package/src/workspace/declared-kinds.ts +40 -1
- package/src/workspace/delivery-metrics.schema.json +519 -0
- package/src/workspace/delivery-metrics.test.ts +236 -0
- package/src/workspace/delivery-metrics.ts +286 -0
- package/src/workspace/flags-read.ts +121 -0
- package/src/workspace/flags.test.ts +141 -0
- package/src/workspace/flags.ts +157 -0
- package/src/workspace/graph-cli.ts +1 -1
- package/src/workspace/intent-cli.ts +46 -5
- package/src/workspace/intent-trace.test.ts +173 -0
- package/src/workspace/intent-trace.ts +484 -0
- package/src/workspace/intent.schema.json +702 -6
- package/src/workspace/intent.ts +148 -25
- package/src/workspace/older-records.test.ts +412 -0
- package/src/workspace/overlap.test.ts +165 -0
- package/src/workspace/overlap.ts +340 -0
- package/src/workspace/pr-report.schema.json +5 -0
- package/src/workspace/read-contract.e2e.test.ts +2 -1
- package/src/workspace/reason-codes.test.ts +5 -0
- package/src/workspace/reason-codes.ts +3 -0
- package/src/workspace/record-assets.test.ts +2 -1
- package/src/workspace/records-contract.e2e.test.ts +2 -1
- package/src/workspace/records.schema.json +21 -2
- package/src/workspace/records.ts +36 -2
- package/src/workspace/reference-kinds/flag/flag.kind.mjs +32 -0
- package/src/workspace/reference-kinds/flag/flag.schema.json +53 -0
- package/src/workspace/releases.schema.json +123 -1
- package/src/workspace/releases.ts +11 -0
- package/src/workspace/run-event.schema.json +24 -6
- package/src/workspace/status-contract.test.ts +29 -0
- package/src/workspace/status-gates.ts +8 -0
- package/src/workspace/status-mixed.test.ts +152 -0
- package/src/workspace/status-revoked.test.ts +153 -0
- package/src/workspace/status-stewards.ts +3 -0
- package/src/workspace/status.schema.json +210 -2
- package/src/workspace/status.ts +254 -3
- package/src/workspace/wip.ts +11 -2
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which releases are revoked (#4033, ws-105 question 2).
|
|
3
|
+
*
|
|
4
|
+
* A release traces to one commit (ws-104), and a commit is revoked when it
|
|
5
|
+
* carries a `ci/revoked/<sha>` tag that counts (ws-103). So a release is
|
|
6
|
+
* revoked exactly when its commit is, and this module derives that at read
|
|
7
|
+
* time from the tags. Nothing is written when a commit is revoked: the tag is
|
|
8
|
+
* the record, `chant ci tick` makes it once, and every reader below judges it
|
|
9
|
+
* the same way.
|
|
10
|
+
*
|
|
11
|
+
* The tags are judged as `release cut` judges them (#4031): with
|
|
12
|
+
* `ci.green.signedSince` declared, a revoked tag without a valid runner
|
|
13
|
+
* statement is ignored and revokes nothing. The declaration and the runner
|
|
14
|
+
* keys are read at base, the green branch's tip on `origin` (or the local
|
|
15
|
+
* branch, or `HEAD`). Only local tags are read; nothing is fetched.
|
|
16
|
+
*
|
|
17
|
+
* The readers:
|
|
18
|
+
*
|
|
19
|
+
* - `chant approve` refuses a release gate whose release is revoked
|
|
20
|
+
* (`release-revoked`), and `chant components promote --release` refuses to
|
|
21
|
+
* deploy one, so a pending gate for it can never pass.
|
|
22
|
+
* - `chant workspace status --json` reads such a gate as `superseded` and
|
|
23
|
+
* flags a component whose environment runs a revoked release, with the
|
|
24
|
+
* rollback line.
|
|
25
|
+
* - `chant release list` marks a revoked release.
|
|
26
|
+
*/
|
|
27
|
+
import type { CiGreen } from "../workspace/declaration.js";
|
|
28
|
+
import type { CiTags, RevokedTagView } from "../workspace/ci-green.js";
|
|
29
|
+
/** A revoked release: the commit it was cut from and the revoked tag on it, as `ci list` shows the tag. */
|
|
30
|
+
export interface ReleaseRevocation extends RevokedTagView {
|
|
31
|
+
/** The release's commit, which the tag names. */
|
|
32
|
+
commit: string;
|
|
33
|
+
}
|
|
34
|
+
/** The stable code `approve` and `promote --release` refuse a revoked release with. */
|
|
35
|
+
export declare const RELEASE_REVOKED_CODE = "release-revoked";
|
|
36
|
+
/**
|
|
37
|
+
* The ci tags at `top`, judged against `green` at base: the green branch's
|
|
38
|
+
* tip on `origin`, else the local branch, else `HEAD`. With no `ci.green`
|
|
39
|
+
* every tag counts. Throws `WorkspaceReadError` (`declaration-invalid`) when
|
|
40
|
+
* `ci.green.signedSince` names no commit here.
|
|
41
|
+
*/
|
|
42
|
+
export declare function judgedCiTags(top: string, green: CiGreen | null): Promise<CiTags>;
|
|
43
|
+
/**
|
|
44
|
+
* Every revoked commit in the repository holding `cwd`, keyed by its full
|
|
45
|
+
* sha, with the declaration's `ci.green` read at base as `release cut` reads
|
|
46
|
+
* it. Empty outside a git repository. Throws `WorkspaceReadError`
|
|
47
|
+
* (`declaration-invalid`) when the tags can't be judged.
|
|
48
|
+
*/
|
|
49
|
+
export declare function readRevokedCommits(cwd: string): Promise<Map<string, ReleaseRevocation>>;
|
|
50
|
+
/** {@link readRevokedCommits} for a caller that has the git top and the declaration's `ci.green` at base already. */
|
|
51
|
+
export declare function revokedCommitsAt(top: string, green: CiGreen | null): Promise<Map<string, ReleaseRevocation>>;
|
|
52
|
+
/** What a reader prints for a release it found revoked: the revocation, the release and its label. */
|
|
53
|
+
export interface RevokedRelease extends ReleaseRevocation {
|
|
54
|
+
releaseDigest: string;
|
|
55
|
+
/** The release's label, or null when its cuts gave it none. */
|
|
56
|
+
label: string | null;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* A memoised lookup from a release digest to its revocation, for the member
|
|
60
|
+
* whose ledger is read from `memberDir`: null when the release is not
|
|
61
|
+
* revoked, or its file can't be read. `revoked` is called on the first
|
|
62
|
+
* lookup only, so a reader that meets no release reads no tags, and no
|
|
63
|
+
* release file is read while no commit is revoked.
|
|
64
|
+
*/
|
|
65
|
+
export declare function revokedReleaseLookup(memberDir: string, revoked: () => Promise<ReadonlyMap<string, ReleaseRevocation>>): (releaseDigest: string) => Promise<RevokedRelease | null>;
|
|
66
|
+
/** Whether `release` is revoked: its commit's revoked tag, or null. */
|
|
67
|
+
export declare function revocationOf(release: {
|
|
68
|
+
commit: string;
|
|
69
|
+
}, revoked: ReadonlyMap<string, ReleaseRevocation>): ReleaseRevocation | null;
|
|
70
|
+
/** What failed, in words: `phase e2e failed in deploy-smoke (Op run r-12 in staging)`. */
|
|
71
|
+
export declare function describeRevocation(r: ReleaseRevocation): string;
|
|
72
|
+
/** The refusal `approve` and `promote --release` print for a revoked release, and the line that fixes it. */
|
|
73
|
+
export declare function revokedRefusal(release: {
|
|
74
|
+
releaseDigest: string;
|
|
75
|
+
label: string | null;
|
|
76
|
+
}, r: ReleaseRevocation, fix: string): {
|
|
77
|
+
message: string;
|
|
78
|
+
hint: string;
|
|
79
|
+
};
|
|
80
|
+
//# sourceMappingURL=release-revocation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"release-revocation.d.ts","sourceRoot":"","sources":["../../src/lifecycle/release-revocation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEpE,2GAA2G;AAC3G,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,uFAAuF;AACvF,eAAO,MAAM,oBAAoB,oBAAoB,CAAC;AAUtD;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAQtF;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAK7F;AAED,qHAAqH;AACrH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAKlH;AAED,sGAAsG;AACtG,MAAM,WAAW,cAAe,SAAQ,iBAAiB;IACvD,aAAa,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,GAC7D,CAAC,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAqB3D;AAED,uEAAuE;AACvE,wBAAgB,YAAY,CAAC,OAAO,EAAE;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,EAAE,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAAG,iBAAiB,GAAG,IAAI,CAEnI;AAED,0FAA0F;AAC1F,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAK/D;AAED,6GAA6G;AAC7G,wBAAgB,cAAc,CAAC,OAAO,EAAE;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,EAAE,CAAC,EAAE,iBAAiB,EAAE,GAAG,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAO7J"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which releases are revoked (#4033, ws-105 question 2).
|
|
3
|
+
*
|
|
4
|
+
* A release traces to one commit (ws-104), and a commit is revoked when it
|
|
5
|
+
* carries a `ci/revoked/<sha>` tag that counts (ws-103). So a release is
|
|
6
|
+
* revoked exactly when its commit is, and this module derives that at read
|
|
7
|
+
* time from the tags. Nothing is written when a commit is revoked: the tag is
|
|
8
|
+
* the record, `chant ci tick` makes it once, and every reader below judges it
|
|
9
|
+
* the same way.
|
|
10
|
+
*
|
|
11
|
+
* The tags are judged as `release cut` judges them (#4031): with
|
|
12
|
+
* `ci.green.signedSince` declared, a revoked tag without a valid runner
|
|
13
|
+
* statement is ignored and revokes nothing. The declaration and the runner
|
|
14
|
+
* keys are read at base, the green branch's tip on `origin` (or the local
|
|
15
|
+
* branch, or `HEAD`). Only local tags are read; nothing is fetched.
|
|
16
|
+
*
|
|
17
|
+
* The readers:
|
|
18
|
+
*
|
|
19
|
+
* - `chant approve` refuses a release gate whose release is revoked
|
|
20
|
+
* (`release-revoked`), and `chant components promote --release` refuses to
|
|
21
|
+
* deploy one, so a pending gate for it can never pass.
|
|
22
|
+
* - `chant workspace status --json` reads such a gate as `superseded` and
|
|
23
|
+
* flags a component whose environment runs a revoked release, with the
|
|
24
|
+
* rollback line.
|
|
25
|
+
* - `chant release list` marks a revoked release.
|
|
26
|
+
*/
|
|
27
|
+
import { execFileSync } from "node:child_process";
|
|
28
|
+
/** The stable code `approve` and `promote --release` refuse a revoked release with. */
|
|
29
|
+
export const RELEASE_REVOKED_CODE = "release-revoked";
|
|
30
|
+
function tryGit(top, args) {
|
|
31
|
+
try {
|
|
32
|
+
return execFileSync("git", args, { cwd: top, encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] }).trim();
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The ci tags at `top`, judged against `green` at base: the green branch's
|
|
40
|
+
* tip on `origin`, else the local branch, else `HEAD`. With no `ci.green`
|
|
41
|
+
* every tag counts. Throws `WorkspaceReadError` (`declaration-invalid`) when
|
|
42
|
+
* `ci.green.signedSince` names no commit here.
|
|
43
|
+
*/
|
|
44
|
+
export async function judgedCiTags(top, green) {
|
|
45
|
+
const { readCiTags } = await import("../workspace/ci-green.js");
|
|
46
|
+
const base = green
|
|
47
|
+
? (tryGit(top, ["rev-parse", "--verify", "--quiet", `refs/remotes/origin/${green.branch}^{commit}`]) ??
|
|
48
|
+
tryGit(top, ["rev-parse", "--verify", "--quiet", `refs/heads/${green.branch}^{commit}`]) ??
|
|
49
|
+
tryGit(top, ["rev-parse", "HEAD"]))
|
|
50
|
+
: null;
|
|
51
|
+
return readCiTags(top, green, base);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Every revoked commit in the repository holding `cwd`, keyed by its full
|
|
55
|
+
* sha, with the declaration's `ci.green` read at base as `release cut` reads
|
|
56
|
+
* it. Empty outside a git repository. Throws `WorkspaceReadError`
|
|
57
|
+
* (`declaration-invalid`) when the tags can't be judged.
|
|
58
|
+
*/
|
|
59
|
+
export async function readRevokedCommits(cwd) {
|
|
60
|
+
const top = tryGit(cwd, ["rev-parse", "--show-toplevel"]);
|
|
61
|
+
if (!top)
|
|
62
|
+
return new Map();
|
|
63
|
+
const { scopeSource } = await import("../workspace/write-scope.js");
|
|
64
|
+
return revokedCommitsAt(top, scopeSource(cwd).declaration?.ci?.green ?? null);
|
|
65
|
+
}
|
|
66
|
+
/** {@link readRevokedCommits} for a caller that has the git top and the declaration's `ci.green` at base already. */
|
|
67
|
+
export async function revokedCommitsAt(top, green) {
|
|
68
|
+
const { revokedTagView } = await import("../workspace/ci-green.js");
|
|
69
|
+
const out = new Map();
|
|
70
|
+
for (const [sha, counted] of (await judgedCiTags(top, green)).revoked)
|
|
71
|
+
out.set(sha, { commit: sha, ...revokedTagView(sha, counted) });
|
|
72
|
+
return out;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* A memoised lookup from a release digest to its revocation, for the member
|
|
76
|
+
* whose ledger is read from `memberDir`: null when the release is not
|
|
77
|
+
* revoked, or its file can't be read. `revoked` is called on the first
|
|
78
|
+
* lookup only, so a reader that meets no release reads no tags, and no
|
|
79
|
+
* release file is read while no commit is revoked.
|
|
80
|
+
*/
|
|
81
|
+
export function revokedReleaseLookup(memberDir, revoked) {
|
|
82
|
+
const seen = new Map();
|
|
83
|
+
let labels;
|
|
84
|
+
return (releaseDigest) => {
|
|
85
|
+
let found = seen.get(releaseDigest);
|
|
86
|
+
if (!found) {
|
|
87
|
+
found = (async () => {
|
|
88
|
+
const commits = await revoked();
|
|
89
|
+
if (commits.size === 0)
|
|
90
|
+
return null;
|
|
91
|
+
const { readRelease, readCuts, labelsByDigest } = await import("./release-store.js");
|
|
92
|
+
const loc = { cwd: memberDir };
|
|
93
|
+
const release = await readRelease(releaseDigest, loc).catch(() => null);
|
|
94
|
+
const r = release ? revocationOf(release, commits) : null;
|
|
95
|
+
if (!r)
|
|
96
|
+
return null;
|
|
97
|
+
labels ?? (labels = readCuts(loc).then((c) => labelsByDigest(c.cuts), () => new Map()));
|
|
98
|
+
return { ...r, releaseDigest, label: (await labels).get(releaseDigest) ?? null };
|
|
99
|
+
})();
|
|
100
|
+
seen.set(releaseDigest, found);
|
|
101
|
+
}
|
|
102
|
+
return found;
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/** Whether `release` is revoked: its commit's revoked tag, or null. */
|
|
106
|
+
export function revocationOf(release, revoked) {
|
|
107
|
+
return revoked.get(release.commit) ?? null;
|
|
108
|
+
}
|
|
109
|
+
/** What failed, in words: `phase e2e failed in deploy-smoke (Op run r-12 in staging)`. */
|
|
110
|
+
export function describeRevocation(r) {
|
|
111
|
+
const run = r.run
|
|
112
|
+
? ` in ${r.run.name}${r.run.opRun ? ` (Op run ${r.run.opRun.id} in ${r.run.opRun.env})` : r.run.id !== null ? ` (run ${r.run.id})` : ""}`
|
|
113
|
+
: "";
|
|
114
|
+
return r.phase !== null ? `phase ${r.phase} failed${run}` : `a required phase failed${run}`;
|
|
115
|
+
}
|
|
116
|
+
/** The refusal `approve` and `promote --release` print for a revoked release, and the line that fixes it. */
|
|
117
|
+
export function revokedRefusal(release, r, fix) {
|
|
118
|
+
return {
|
|
119
|
+
message: `release ${release.label ?? release.releaseDigest} was cut from commit ${r.commit.slice(0, 12)}, which ${r.tag} revokes ` +
|
|
120
|
+
`(${describeRevocation(r)}), so it is not deployed and no approval of it counts [${RELEASE_REVOKED_CODE}]`,
|
|
121
|
+
hint: fix,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
@@ -89,7 +89,16 @@ export interface ReleaseCut {
|
|
|
89
89
|
label: string | null;
|
|
90
90
|
actor: string;
|
|
91
91
|
timestamp: string;
|
|
92
|
-
/**
|
|
92
|
+
/**
|
|
93
|
+
* The run the cut ran in (#4027): the CI run's id in CI, or an id minted on
|
|
94
|
+
* the machine that cut (`local-<epoch ms>`). Null on every cut written
|
|
95
|
+
* before 0.124.29.
|
|
96
|
+
*/
|
|
97
|
+
runId: string | null;
|
|
98
|
+
/**
|
|
99
|
+
* Where that run ran: the CI run's origin, or `{ forge: "local" }` for a
|
|
100
|
+
* minted id (#4027). A cut written before 0.124.29 holds null outside CI.
|
|
101
|
+
*/
|
|
93
102
|
runOrigin: RunOrigin | null;
|
|
94
103
|
/**
|
|
95
104
|
* The cut's signature (#4031): an armored ssh signature by the actor's key
|
|
@@ -172,8 +181,9 @@ export type CutOutcome = {
|
|
|
172
181
|
* cut, and cutting a digest under a label other than its own, or under a
|
|
173
182
|
* label another digest has, throws {@link ReleaseLabelError}. Does not push.
|
|
174
183
|
*/
|
|
175
|
-
export declare function appendCut(input: Omit<ReleaseCut, "version" | "signature"> & {
|
|
184
|
+
export declare function appendCut(input: Omit<ReleaseCut, "version" | "signature" | "runId"> & {
|
|
176
185
|
signature?: string | null;
|
|
186
|
+
runId?: string | null;
|
|
177
187
|
}, opts?: {
|
|
178
188
|
cwd?: string;
|
|
179
189
|
}): Promise<CutOutcome>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"release-store.d.ts","sourceRoot":"","sources":["../../src/lifecycle/release-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAKH,OAAO,EASL,KAAK,cAAc,EACpB,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,uFAAuF;AACvF,eAAO,MAAM,YAAY,cAAc,CAAC;AACxC,+CAA+C;AAC/C,eAAO,MAAM,SAAS,eAAe,CAAC;AACtC,6FAA6F;AAC7F,eAAO,MAAM,gBAAgB,cAAc,CAAC;AAE5C,0GAA0G;AAC1G,eAAO,MAAM,mBAAmB,YAAY,CAAC;AAE7C,6FAA6F;AAC7F,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IACxB,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,0GAA0G;AAC1G,MAAM,WAAW,eAAe;IAC9B,qFAAqF;IACrF,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,gDAAgD;AAChD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IACjC,+FAA+F;IAC/F,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wCAAwC;AACxC,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,MAAM,EAAE,YAAY,EAAE,CAAC;CACxB;AAED,0DAA0D;AAC1D,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,CAAC,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,wGAAwG;IACxG,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,eAAe,EAAE,CAAC;IACnC,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED,0CAA0C;AAC1C,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,CAAC,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,oFAAoF;IACpF,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,
|
|
1
|
+
{"version":3,"file":"release-store.d.ts","sourceRoot":"","sources":["../../src/lifecycle/release-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -211,12 +211,13 @@ export function parseCuts(text) {
|
|
|
211
211
|
typeof c.actor === "string" &&
|
|
212
212
|
typeof c.timestamp === "string" &&
|
|
213
213
|
(c.runOrigin === null || (typeof c.runOrigin === "object" && typeof c.runOrigin?.forge === "string")) &&
|
|
214
|
-
(c.signature === null || c.signature === undefined || typeof c.signature === "string")
|
|
214
|
+
(c.signature === null || c.signature === undefined || typeof c.signature === "string") &&
|
|
215
|
+
(c.runId === null || c.runId === undefined || typeof c.runId === "string");
|
|
215
216
|
if (!ok) {
|
|
216
217
|
malformed++;
|
|
217
218
|
continue;
|
|
218
219
|
}
|
|
219
|
-
cuts.push({ ...c, signature: c.signature ?? null });
|
|
220
|
+
cuts.push({ ...c, runId: c.runId ?? null, signature: c.signature ?? null });
|
|
220
221
|
}
|
|
221
222
|
catch {
|
|
222
223
|
malformed++;
|
|
@@ -278,6 +279,7 @@ export async function appendCut(input, opts) {
|
|
|
278
279
|
label: input.label,
|
|
279
280
|
actor: input.actor,
|
|
280
281
|
timestamp: input.timestamp,
|
|
282
|
+
runId: input.runId ?? null,
|
|
281
283
|
runOrigin: input.runOrigin,
|
|
282
284
|
signature: input.signature ?? null,
|
|
283
285
|
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `chant release verify <label|digest>` (#4049): whether a release was
|
|
3
|
+
* signed by a key `.chant/allowed_signers` lists, checked offline.
|
|
4
|
+
*
|
|
5
|
+
* It reads the release and its cuts from the local `chant/lifecycle` branch,
|
|
6
|
+
* and the signers file, its signed history (#2553) and the declaration at the
|
|
7
|
+
* release's own commit, as `chant workspace evidence verify` reads the policy
|
|
8
|
+
* at the revision it is given. It fetches nothing and needs no key. A release
|
|
9
|
+
* verifies when its file's digest is the digest of what it holds and one of
|
|
10
|
+
* its cuts carries a signature in the `chant-release` namespace that verifies
|
|
11
|
+
* for the cut's actor, over the release digest, the label, the actor and the
|
|
12
|
+
* time (`releaseSealPayload`), and, when the declaration at that commit has an
|
|
13
|
+
* `identity.gates.release` entry naming a class, the actor is in it.
|
|
14
|
+
*
|
|
15
|
+
* Reading the signers at the release's commit means a key added later does
|
|
16
|
+
* not make an old release verify, and one removed later does not unmake it.
|
|
17
|
+
*/
|
|
18
|
+
import type { ReleaseSignatureCheck } from "../workspace/identity-gate-rule.js";
|
|
19
|
+
import type { ReleaseCut } from "./release-store.js";
|
|
20
|
+
/** What `release verify --json` prints. */
|
|
21
|
+
export interface ReleaseVerification {
|
|
22
|
+
releaseDigest: string;
|
|
23
|
+
label: string | null;
|
|
24
|
+
member: string | null;
|
|
25
|
+
commit: string;
|
|
26
|
+
/** Where the signers were read: the signers file's path and the commit. */
|
|
27
|
+
signers: {
|
|
28
|
+
path: string;
|
|
29
|
+
at: string;
|
|
30
|
+
active: boolean;
|
|
31
|
+
};
|
|
32
|
+
/** True when the release file's digest is the digest of what it holds. */
|
|
33
|
+
digestMatches: boolean;
|
|
34
|
+
/** `verified` when a cut's signature verifies; `unsigned` when no cut carries one; `unverified` otherwise. */
|
|
35
|
+
status: "verified" | "unsigned" | "unverified";
|
|
36
|
+
/** The cut whose signature verified, or null. */
|
|
37
|
+
verifiedBy: {
|
|
38
|
+
actor: string;
|
|
39
|
+
key: string | null;
|
|
40
|
+
} | null;
|
|
41
|
+
reason: string;
|
|
42
|
+
cuts: Array<Pick<ReleaseCut, "label" | "actor" | "timestamp" | "runId"> & {
|
|
43
|
+
signatureCheck: ReleaseSignatureCheck;
|
|
44
|
+
}>;
|
|
45
|
+
}
|
|
46
|
+
/** Why a release could not be checked at all. */
|
|
47
|
+
export interface ReleaseVerifyError {
|
|
48
|
+
code: "release-not-found" | "release-commit-missing" | "trust-policy-unreadable" | "not-a-git-repository";
|
|
49
|
+
message: string;
|
|
50
|
+
fix?: string;
|
|
51
|
+
}
|
|
52
|
+
/** The exit-1 codes of a release that was checked and did not verify. */
|
|
53
|
+
export declare function verificationCode(v: ReleaseVerification): "release-digest-mismatch" | "release-unsigned" | "release-signature-unverified" | null;
|
|
54
|
+
/** Check the release `ref` names in the member at `cwd`. Reads only the local repository. */
|
|
55
|
+
export declare function verifyRelease(req: {
|
|
56
|
+
cwd: string;
|
|
57
|
+
ref: string;
|
|
58
|
+
}): Promise<ReleaseVerification | {
|
|
59
|
+
error: ReleaseVerifyError;
|
|
60
|
+
}>;
|
|
61
|
+
//# sourceMappingURL=release-verify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"release-verify.d.ts","sourceRoot":"","sources":["../../src/lifecycle/release-verify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,KAAK,EAAW,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE3D,2CAA2C;AAC3C,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC;IACvD,0EAA0E;IAC1E,aAAa,EAAE,OAAO,CAAC;IACvB,8GAA8G;IAC9G,MAAM,EAAE,UAAU,GAAG,UAAU,GAAG,YAAY,CAAC;IAC/C,iDAAiD;IACjD,UAAU,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IACzD,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,GAAG,OAAO,GAAG,WAAW,GAAG,OAAO,CAAC,GAAG;QAAE,cAAc,EAAE,qBAAqB,CAAA;KAAE,CAAC,CAAC;CACtH;AAED,iDAAiD;AACjD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,mBAAmB,GAAG,wBAAwB,GAAG,yBAAyB,GAAG,sBAAsB,CAAC;IAC1G,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,mBAAmB,GAAG,yBAAyB,GAAG,kBAAkB,GAAG,8BAA8B,GAAG,IAAI,CAI/I;AAED,6FAA6F;AAC7F,wBAAsB,aAAa,CAAC,GAAG,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,mBAAmB,GAAG;IAAE,KAAK,EAAE,kBAAkB,CAAA;CAAE,CAAC,CAiEnI"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `chant release verify <label|digest>` (#4049): whether a release was
|
|
3
|
+
* signed by a key `.chant/allowed_signers` lists, checked offline.
|
|
4
|
+
*
|
|
5
|
+
* It reads the release and its cuts from the local `chant/lifecycle` branch,
|
|
6
|
+
* and the signers file, its signed history (#2553) and the declaration at the
|
|
7
|
+
* release's own commit, as `chant workspace evidence verify` reads the policy
|
|
8
|
+
* at the revision it is given. It fetches nothing and needs no key. A release
|
|
9
|
+
* verifies when its file's digest is the digest of what it holds and one of
|
|
10
|
+
* its cuts carries a signature in the `chant-release` namespace that verifies
|
|
11
|
+
* for the cut's actor, over the release digest, the label, the actor and the
|
|
12
|
+
* time (`releaseSealPayload`), and, when the declaration at that commit has an
|
|
13
|
+
* `identity.gates.release` entry naming a class, the actor is in it.
|
|
14
|
+
*
|
|
15
|
+
* Reading the signers at the release's commit means a key added later does
|
|
16
|
+
* not make an old release verify, and one removed later does not unmake it.
|
|
17
|
+
*/
|
|
18
|
+
/** The exit-1 codes of a release that was checked and did not verify. */
|
|
19
|
+
export function verificationCode(v) {
|
|
20
|
+
if (!v.digestMatches)
|
|
21
|
+
return "release-digest-mismatch";
|
|
22
|
+
if (v.status === "verified")
|
|
23
|
+
return null;
|
|
24
|
+
return v.status === "unsigned" ? "release-unsigned" : "release-signature-unverified";
|
|
25
|
+
}
|
|
26
|
+
/** Check the release `ref` names in the member at `cwd`. Reads only the local repository. */
|
|
27
|
+
export async function verifyRelease(req) {
|
|
28
|
+
const { resolveRelease, readCuts, verifyReleaseDigest } = await import("./release-store.js");
|
|
29
|
+
const { gitRoot } = await import("../workspace/record-source.js");
|
|
30
|
+
const { resolveBase } = await import("../workspace/trust/provenance.js");
|
|
31
|
+
const { scopeSource } = await import("../workspace/write-scope.js");
|
|
32
|
+
const { releaseRuleFrom } = await import("../workspace/identity.js");
|
|
33
|
+
const { checkReleaseSignature } = await import("../workspace/identity-gate-rule.js");
|
|
34
|
+
const { cwd, ref } = req;
|
|
35
|
+
const top = gitRoot(cwd);
|
|
36
|
+
if (!top)
|
|
37
|
+
return { error: { code: "not-a-git-repository", message: "a release is checked against the signers file at its commit, and this directory is not in a git repository" } };
|
|
38
|
+
const found = await resolveRelease(ref, { cwd });
|
|
39
|
+
if (!found)
|
|
40
|
+
return { error: { code: "release-not-found", message: `no release is labelled or digested "${ref}" in this member`, fix: "Fetch chant/lifecycle (git fetch origin chant/lifecycle:chant/lifecycle), then list them with: chant release list" } };
|
|
41
|
+
const release = found.release;
|
|
42
|
+
const at = resolveBase(top, release.commit).commit;
|
|
43
|
+
if (!at) {
|
|
44
|
+
return {
|
|
45
|
+
error: {
|
|
46
|
+
code: "release-commit-missing",
|
|
47
|
+
message: `the release's commit ${release.commit} is not in this clone, so the signers file at it can't be read`,
|
|
48
|
+
fix: `Fetch it: git fetch origin ${release.commit}`,
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
const source = scopeSource(cwd, at);
|
|
53
|
+
if (source.policy.problems.length > 0) {
|
|
54
|
+
return { error: { code: "trust-policy-unreadable", message: `the signers at ${at.slice(0, 12)} can't be read: ${source.policy.problems.join("; ")}` } };
|
|
55
|
+
}
|
|
56
|
+
const read = releaseRuleFrom(source);
|
|
57
|
+
// A declaration read from the working tree is not the commit's, so its class does not apply.
|
|
58
|
+
const rule = source.from === "base" ? read.rule : { ...read.rule, class: null };
|
|
59
|
+
const own = (await readCuts({ cwd })).cuts.filter((c) => c.releaseDigest === release.releaseDigest);
|
|
60
|
+
// The check words where it read the signers as "at base"; here that is the release's commit.
|
|
61
|
+
const atCommit = (check) => ({ ...check, reason: check.reason.split(`${rule.signers.signersPath} at base`).join(`${rule.signers.signersPath} at ${at.slice(0, 12)}`) });
|
|
62
|
+
const cuts = own.map((c) => ({
|
|
63
|
+
label: c.label,
|
|
64
|
+
actor: c.actor,
|
|
65
|
+
timestamp: c.timestamp,
|
|
66
|
+
runId: c.runId ?? null,
|
|
67
|
+
signatureCheck: atCommit(checkReleaseSignature(rule, { releaseDigest: c.releaseDigest, label: c.label, actor: c.actor, timestamp: c.timestamp, signature: c.signature })),
|
|
68
|
+
}));
|
|
69
|
+
const verified = cuts.find((c) => c.signatureCheck.status === "verified");
|
|
70
|
+
const digestMatches = verifyReleaseDigest(release);
|
|
71
|
+
const status = verified ? "verified" : cuts.every((c) => c.signatureCheck.status === "unsigned") ? "unsigned" : "unverified";
|
|
72
|
+
const where = `${rule.signers.signersPath} at ${at.slice(0, 12)}`;
|
|
73
|
+
const reason = !digestMatches
|
|
74
|
+
? `the release file's digest ${release.releaseDigest} is not the digest of what it holds, so it was changed after the cut`
|
|
75
|
+
: verified
|
|
76
|
+
? `${verified.signatureCheck.reason}, checked against ${where}`
|
|
77
|
+
: status === "unsigned"
|
|
78
|
+
? `no cut of the release carries a signature`
|
|
79
|
+
: cuts.map((c) => c.signatureCheck.reason).join("; ");
|
|
80
|
+
return {
|
|
81
|
+
releaseDigest: release.releaseDigest,
|
|
82
|
+
label: found.label,
|
|
83
|
+
member: release.member,
|
|
84
|
+
commit: release.commit,
|
|
85
|
+
signers: { path: rule.signers.signersPath, at, active: rule.signers.active },
|
|
86
|
+
digestMatches,
|
|
87
|
+
status: digestMatches ? status : "unverified",
|
|
88
|
+
verifiedBy: digestMatches && verified ? { actor: verified.actor, key: verified.signatureCheck.key } : null,
|
|
89
|
+
reason,
|
|
90
|
+
cuts,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cutting a release from a workstation as from CI (#4027).
|
|
3
|
+
*
|
|
4
|
+
* `chant release cut` runs the same steps wherever it runs. What differs
|
|
5
|
+
* between a laptop and a CI job is read here, from git and the process
|
|
6
|
+
* environment, so the CLI and its tests resolve it the same way:
|
|
7
|
+
*
|
|
8
|
+
* - trunk: the branch `ci.green.branch` names in the declaration at base,
|
|
9
|
+
* else the branch `origin/HEAD` points at, else `main`. The commit must be
|
|
10
|
+
* reachable from `origin/<branch>` as this clone last fetched it, so a
|
|
11
|
+
* commit that is on the local branch only is refused as not pushed. Nothing
|
|
12
|
+
* is fetched: a stale `origin/<branch>` can only refuse a commit that was
|
|
13
|
+
* pushed since, never admit one that wasn't.
|
|
14
|
+
* - a clean tree: no tracked change and no untracked file that git does not
|
|
15
|
+
* ignore, since the compile reads the directory and a new
|
|
16
|
+
* `*.component.ts` would be compiled into the release.
|
|
17
|
+
* - the actor: `--actor`, else the principal the signers file at base lists
|
|
18
|
+
* for the signing key, else the CI's actor, else git's `user.email`, else
|
|
19
|
+
* `$USER`.
|
|
20
|
+
* - the tag: `release/<label>`, or `release/<member>/<label>` in a workspace
|
|
21
|
+
* member, an annotated tag on the commit that is created locally and never
|
|
22
|
+
* pushed by chant.
|
|
23
|
+
*/
|
|
24
|
+
import type { Signer } from "../workspace/trust/trust-files.js";
|
|
25
|
+
export type WorkstationCheckCode = "release-commit-not-on-trunk" | "release-commit-not-pushed" | "release-worktree-dirty" | "release-tag-taken" | "release-tag-invalid";
|
|
26
|
+
/** A refusal before anything is compiled or written. */
|
|
27
|
+
export declare class WorkstationCheckError extends Error {
|
|
28
|
+
readonly code: WorkstationCheckCode;
|
|
29
|
+
readonly fix?: string | undefined;
|
|
30
|
+
constructor(code: WorkstationCheckCode, message: string, fix?: string | undefined);
|
|
31
|
+
}
|
|
32
|
+
/** The remote a release's commit must be pushed to. */
|
|
33
|
+
export declare const RELEASE_REMOTE = "origin";
|
|
34
|
+
/** The trunk branch, and where its name came from. */
|
|
35
|
+
export interface Trunk {
|
|
36
|
+
remote: string;
|
|
37
|
+
branch: string;
|
|
38
|
+
from: "ci.green.branch" | "origin/HEAD" | "default";
|
|
39
|
+
}
|
|
40
|
+
/** The trunk of the repository at `cwd`: `ci.green.branch` when declared, else what `origin/HEAD` names, else `main`. */
|
|
41
|
+
export declare function resolveTrunk(cwd: string, greenBranch: string | null): Trunk;
|
|
42
|
+
/**
|
|
43
|
+
* Refuse `commit` unless it is reachable from `<remote>/<branch>` as this
|
|
44
|
+
* clone knows it. A commit on the local branch only is `release-commit-not-pushed`;
|
|
45
|
+
* any other is `release-commit-not-on-trunk`.
|
|
46
|
+
*/
|
|
47
|
+
export declare function checkOnTrunk(cwd: string, commit: string, trunk: Trunk): void;
|
|
48
|
+
/** Refuse a tree with a tracked change or an untracked file git does not ignore. */
|
|
49
|
+
export declare function checkCleanTree(cwd: string, commit: string): void;
|
|
50
|
+
/** Where the actor came from. */
|
|
51
|
+
export type ActorSource = "flag" | "signer" | "ci" | "git" | "user";
|
|
52
|
+
/** The public key `keyFile` holds or names, as `<type> <base64>`, or null when it can't be read without a passphrase. */
|
|
53
|
+
export declare function publicKeyOf(keyFile: string): string | null;
|
|
54
|
+
/** The one principal `signers` lists for `publicKey`, or null for none or several. */
|
|
55
|
+
export declare function signerPrincipal(publicKey: string, signers: readonly Signer[]): string | null;
|
|
56
|
+
/**
|
|
57
|
+
* Who cut the release, and where the name came from: `--actor`, else the
|
|
58
|
+
* signer the signers file at base lists for the signing key, else the CI's
|
|
59
|
+
* actor (`GITHUB_ACTOR`, `GITLAB_USER_LOGIN`), else git's `user.email`, else
|
|
60
|
+
* `$USER`. Undefined when none is set.
|
|
61
|
+
*/
|
|
62
|
+
export declare function resolveCutActor(req: {
|
|
63
|
+
cwd: string;
|
|
64
|
+
explicit?: string;
|
|
65
|
+
/** The signing key's public half, when the cut is signed and it could be read. */
|
|
66
|
+
publicKey?: string | null;
|
|
67
|
+
signers?: readonly Signer[];
|
|
68
|
+
env?: NodeJS.ProcessEnv;
|
|
69
|
+
}): {
|
|
70
|
+
actor: string;
|
|
71
|
+
source: ActorSource;
|
|
72
|
+
} | undefined;
|
|
73
|
+
/** The tag a labelled release gets: `release/<label>`, or `release/<member>/<label>` for a workspace member. */
|
|
74
|
+
export declare function releaseTagName(member: string | null, label: string): string;
|
|
75
|
+
/**
|
|
76
|
+
* Whether `tag` can name `commit`: `absent` (the cut creates it), `present`
|
|
77
|
+
* (it already names the commit), or a {@link WorkstationCheckError} for a
|
|
78
|
+
* tag that names another commit or is not a valid tag name.
|
|
79
|
+
*/
|
|
80
|
+
export declare function checkReleaseTag(cwd: string, tag: string, commit: string): "absent" | "present";
|
|
81
|
+
/**
|
|
82
|
+
* Create `tag` on `commit` as an annotated tag whose message names the
|
|
83
|
+
* release. Local only. A clone with no git identity tags as chant, as the ci
|
|
84
|
+
* tags are made.
|
|
85
|
+
*/
|
|
86
|
+
export declare function createReleaseTag(cwd: string, tag: string, commit: string, release: {
|
|
87
|
+
releaseDigest: string;
|
|
88
|
+
label: string;
|
|
89
|
+
member: string | null;
|
|
90
|
+
}): void;
|
|
91
|
+
//# sourceMappingURL=release-workstation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"release-workstation.d.ts","sourceRoot":"","sources":["../../src/lifecycle/release-workstation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gCAAgC,CAAC;AAE7D,MAAM,MAAM,oBAAoB,GAAG,6BAA6B,GAAG,2BAA2B,GAAG,wBAAwB,GAAG,mBAAmB,GAAG,qBAAqB,CAAC;AAExK,wDAAwD;AACxD,qBAAa,qBAAsB,SAAQ,KAAK;IAE5C,QAAQ,CAAC,IAAI,EAAE,oBAAoB;IAEnC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM;IAHvB,YACW,IAAI,EAAE,oBAAoB,EACnC,OAAO,EAAE,MAAM,EACN,GAAG,CAAC,EAAE,MAAM,YAAA,EAItB;CACF;AAaD,uDAAuD;AACvD,eAAO,MAAM,cAAc,WAAW,CAAC;AAEvC,sDAAsD;AACtD,MAAM,WAAW,KAAK;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,iBAAiB,GAAG,aAAa,GAAG,SAAS,CAAC;CACrD;AAED,yHAAyH;AACzH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,KAAK,CAM3E;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAwB5E;AAED,oFAAoF;AACpF,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAehE;AAED,iCAAiC;AACjC,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,QAAQ,GAAG,IAAI,GAAG,KAAK,GAAG,MAAM,CAAC;AAEpE,yHAAyH;AACzH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAmB1D;AAED,sFAAsF;AACtF,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAG5F;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kFAAkF;IAClF,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,GAAG,SAAS,CAarD;AAED,gHAAgH;AAChH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE3E;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAY9F;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,CAMzJ"}
|