@intentius/chant 0.124.27 → 0.124.29
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/README.md +1 -1
- package/dist/__golden__/wave-loop/fan-out-gated.json +8 -0
- package/dist/__golden__/wave-loop/fan-out-no-members.json +4 -0
- package/dist/__golden__/wave-loop/fan-out-only.json +6 -0
- package/dist/__golden__/wave-loop/op-by-apply-hold.json +2 -0
- package/dist/__golden__/wave-loop/op-cost-member.json +3 -0
- package/dist/__golden__/wave-loop/op-held-on-before-apply.json +1 -0
- package/dist/__golden__/wave-loop/op-held-on.json +2 -0
- package/dist/__golden__/wave-loop/op-hooks-held.json +2 -0
- package/dist/__golden__/wave-loop/op-hooks-hold-before-apply.json +2 -0
- package/dist/__golden__/wave-loop/op-hooks-refused-at-base.json +3 -0
- package/dist/__golden__/wave-loop/op-hooks-share.json +3 -0
- package/dist/__golden__/wave-loop/op-per-run.json +7 -0
- package/dist/__golden__/wave-loop/op-pr-review.json +7 -0
- package/dist/__golden__/wave-loop/op-sealed.json +3 -0
- package/dist/__golden__/wave-loop/op-spend.json +3 -0
- package/dist/__golden__/wave-loop/op-wave-commands.json +7 -0
- package/dist/__golden__/wave-loop/op-wide-waiting.json +4 -0
- 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 +63 -0
- package/dist/change-set-graph.d.ts.map +1 -0
- package/dist/change-set-graph.js +130 -0
- package/dist/change-set.d.ts +62 -3
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +36 -4
- package/dist/chant-version.d.ts +9 -0
- package/dist/chant-version.d.ts.map +1 -0
- package/dist/chant-version.js +16 -0
- 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 +8 -0
- package/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/commands/build.js +15 -11
- package/dist/cli/commands/check-lexicon-docs.d.ts.map +1 -1
- package/dist/cli/commands/check-lexicon-docs.js +30 -2
- package/dist/cli/commands/check-lexicon.d.ts.map +1 -1
- package/dist/cli/commands/check-lexicon.js +13 -2
- package/dist/cli/commands/init-lexicon/templates/docs.d.ts +4 -1
- package/dist/cli/commands/init-lexicon/templates/docs.d.ts.map +1 -1
- package/dist/cli/commands/init-lexicon/templates/docs.js +6 -6
- package/dist/cli/commands/init-lexicon.d.ts.map +1 -1
- package/dist/cli/commands/init-lexicon.js +17 -8
- package/dist/cli/handlers/approve.d.ts.map +1 -1
- package/dist/cli/handlers/approve.js +64 -4
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/build.js +43 -4
- package/dist/cli/handlers/change-set.d.ts +10 -0
- package/dist/cli/handlers/change-set.d.ts.map +1 -1
- package/dist/cli/handlers/change-set.js +51 -1
- package/dist/cli/handlers/fan-out.d.ts +10 -1
- package/dist/cli/handlers/fan-out.d.ts.map +1 -1
- package/dist/cli/handlers/fan-out.js +54 -6
- 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 +16 -2
- package/dist/cli/handlers/pr.d.ts.map +1 -1
- package/dist/cli/handlers/pr.js +269 -37
- 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 +440 -28
- package/dist/cli/handlers/release.d.ts +91 -0
- package/dist/cli/handlers/release.d.ts.map +1 -0
- package/dist/cli/handlers/release.js +589 -0
- package/dist/cli/handlers/run.d.ts +38 -2
- package/dist/cli/handlers/run.d.ts.map +1 -1
- package/dist/cli/handlers/run.js +234 -16
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +143 -17
- package/dist/cli/mcp/workspace-tools.js +1 -1
- package/dist/cli/parse-args.d.ts.map +1 -1
- package/dist/cli/parse-args.js +73 -5
- package/dist/cli/registry.d.ts +43 -5
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/cli/run-events.d.ts +30 -0
- package/dist/cli/run-events.d.ts.map +1 -0
- package/dist/cli/run-events.js +49 -0
- package/dist/cli/version.d.ts +3 -5
- package/dist/cli/version.d.ts.map +1 -1
- package/dist/cli/version.js +3 -13
- package/dist/codegen/docs-in-site.d.ts +71 -0
- package/dist/codegen/docs-in-site.d.ts.map +1 -0
- package/dist/codegen/docs-in-site.js +177 -0
- package/dist/codegen/docs-types.d.ts +14 -1
- package/dist/codegen/docs-types.d.ts.map +1 -1
- package/dist/codegen/docs.d.ts +18 -1
- package/dist/codegen/docs.d.ts.map +1 -1
- package/dist/codegen/docs.js +40 -7
- package/dist/codegen/rehype-base-url.mjs +15 -9
- package/dist/components/auto-release.d.ts +6 -1
- package/dist/components/auto-release.d.ts.map +1 -1
- package/dist/components/auto-release.js +3 -0
- package/dist/components/capability.d.ts +9 -0
- package/dist/components/capability.d.ts.map +1 -1
- package/dist/components/cli-support.d.ts +6 -0
- package/dist/components/cli-support.d.ts.map +1 -1
- package/dist/components/cli-support.js +10 -9
- package/dist/components/driver.d.ts +50 -9
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/driver.js +116 -54
- 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 +7 -0
- package/dist/components/fan-out-run.d.ts.map +1 -1
- package/dist/components/fan-out-run.js +85 -26
- 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 +25 -0
- package/dist/components/pr-pipeline.d.ts.map +1 -1
- package/dist/components/pr-pipeline.js +22 -4
- package/dist/components/pr-run.d.ts +11 -0
- package/dist/components/pr-run.d.ts.map +1 -1
- package/dist/components/pr-run.js +20 -1
- package/dist/components/promote-order.d.ts +38 -0
- package/dist/components/promote-order.d.ts.map +1 -0
- package/dist/components/promote-order.js +62 -0
- package/dist/components/promote.d.ts +38 -2
- package/dist/components/promote.d.ts.map +1 -1
- package/dist/components/promote.js +77 -2
- package/dist/components/release-compile.d.ts +142 -0
- package/dist/components/release-compile.d.ts.map +1 -0
- package/dist/components/release-compile.js +382 -0
- package/dist/components/release-gate.d.ts +135 -0
- package/dist/components/release-gate.d.ts.map +1 -0
- package/dist/components/release-gate.js +288 -0
- package/dist/components/release-promote.d.ts +96 -0
- package/dist/components/release-promote.d.ts.map +1 -0
- package/dist/components/release-promote.js +204 -0
- package/dist/components/run-progress.d.ts +7 -0
- package/dist/components/run-progress.d.ts.map +1 -1
- package/dist/components/wave-plan.d.ts +8 -1
- package/dist/components/wave-plan.d.ts.map +1 -1
- package/dist/components/wave-plan.js +11 -3
- package/dist/config.d.ts +45 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -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/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -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 +68 -0
- package/dist/lifecycle/change-set-store.d.ts.map +1 -0
- package/dist/lifecycle/change-set-store.js +97 -0
- package/dist/lifecycle/commit-sha.d.ts +13 -0
- package/dist/lifecycle/commit-sha.d.ts.map +1 -0
- package/dist/lifecycle/commit-sha.js +21 -0
- 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 +78 -0
- package/dist/lifecycle/gate-change-set.d.ts.map +1 -0
- package/dist/lifecycle/gate-change-set.js +138 -0
- package/dist/lifecycle/gate-ledger.d.ts +51 -4
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
- package/dist/lifecycle/gate-ledger.js +18 -0
- 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 +154 -0
- package/dist/lifecycle/release-cut.d.ts.map +1 -0
- package/dist/lifecycle/release-cut.js +366 -0
- 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 +54 -0
- package/dist/lifecycle/release-ledger.d.ts.map +1 -1
- package/dist/lifecycle/release-ledger.js +53 -20
- 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 +200 -0
- package/dist/lifecycle/release-store.d.ts.map +1 -0
- package/dist/lifecycle/release-store.js +320 -0
- 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 +4 -0
- package/dist/lifecycle/run-ledger.d.ts.map +1 -1
- package/dist/lifecycle/run-ledger.js +2 -0
- package/dist/op/activities/change-coverage.d.ts.map +1 -1
- package/dist/op/activities/change-coverage.js +4 -2
- package/dist/op/activities/source-release.d.ts.map +1 -1
- package/dist/op/activities/source-release.js +7 -3
- package/dist/op/activities/source-rollback.d.ts.map +1 -1
- package/dist/op/activities/source-rollback.js +7 -3
- package/dist/op/gate-name.d.ts +11 -2
- package/dist/op/gate-name.d.ts.map +1 -1
- package/dist/op/gate-name.js +12 -3
- package/dist/op/gate-run-locator.d.ts +22 -0
- package/dist/op/gate-run-locator.d.ts.map +1 -1
- package/dist/op/gate-run-locator.js +31 -0
- package/dist/op/gate.d.ts +27 -3
- package/dist/op/gate.d.ts.map +1 -1
- package/dist/op/gate.js +57 -3
- package/dist/op/local-executor.d.ts +36 -1
- package/dist/op/local-executor.d.ts.map +1 -1
- package/dist/op/local-executor.js +158 -52
- package/dist/op/op-waves-run.d.ts.map +1 -1
- package/dist/op/op-waves-run.js +4 -0
- package/dist/op/run-live.d.ts +2 -0
- package/dist/op/run-live.d.ts.map +1 -1
- package/dist/op/run-live.js +1 -1
- package/dist/op/runtime.d.ts +46 -0
- package/dist/op/runtime.d.ts.map +1 -1
- package/dist/op/runtimes/local.d.ts.map +1 -1
- package/dist/op/runtimes/local.js +8 -0
- package/dist/plan-summary.d.ts.map +1 -1
- package/dist/plan-summary.js +8 -2
- package/dist/point-decision.d.ts +2 -0
- package/dist/point-decision.d.ts.map +1 -1
- package/dist/point-decision.js +9 -2
- package/dist/pr-loop.d.ts +7 -0
- package/dist/pr-loop.d.ts.map +1 -1
- package/dist/pr-loop.js +23 -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 +104 -0
- package/dist/run-event-store.d.ts.map +1 -0
- package/dist/run-event-store.js +251 -0
- package/dist/run-event-stream.d.ts +133 -0
- package/dist/run-event-stream.d.ts.map +1 -0
- package/dist/run-event-stream.js +242 -0
- package/dist/run-event.d.ts +285 -0
- package/dist/run-event.d.ts.map +1 -0
- package/dist/run-event.js +209 -0
- package/dist/wave-runtime.mjs +262 -226
- 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/__fixtures__/run-event-check.d.ts +19 -0
- package/dist/workspace/__fixtures__/run-event-check.d.ts.map +1 -0
- package/dist/workspace/__fixtures__/run-event-check.js +59 -0
- package/dist/workspace/change-set-show.d.ts +56 -0
- package/dist/workspace/change-set-show.d.ts.map +1 -0
- package/dist/workspace/change-set-show.js +54 -0
- package/dist/workspace/change-set-show.schema.json +102 -0
- package/dist/workspace/change-set.schema.json +32 -1
- package/dist/workspace/changes-cli.d.ts.map +1 -1
- package/dist/workspace/changes-cli.js +10 -1
- package/dist/workspace/changes.d.ts +37 -0
- package/dist/workspace/changes.d.ts.map +1 -1
- package/dist/workspace/changes.js +49 -2
- package/dist/workspace/changes.schema.json +135 -0
- 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-cli.d.ts +19 -4
- package/dist/workspace/ci-green-cli.d.ts.map +1 -1
- package/dist/workspace/ci-green-cli.js +75 -12
- package/dist/workspace/ci-green-forge.d.ts +20 -3
- package/dist/workspace/ci-green-forge.d.ts.map +1 -1
- package/dist/workspace/ci-green-forge.js +6 -4
- package/dist/workspace/ci-green-workflow.d.ts +11 -0
- package/dist/workspace/ci-green-workflow.d.ts.map +1 -1
- package/dist/workspace/ci-green-workflow.js +6 -0
- package/dist/workspace/ci-green.d.ts +281 -13
- package/dist/workspace/ci-green.d.ts.map +1 -1
- package/dist/workspace/ci-green.js +456 -38
- package/dist/workspace/ci-last-green.schema.json +32 -2
- package/dist/workspace/ci-list.schema.json +525 -0
- package/dist/workspace/commit-links.d.ts +85 -0
- package/dist/workspace/commit-links.d.ts.map +1 -0
- package/dist/workspace/commit-links.js +163 -0
- package/dist/workspace/declaration.d.ts +35 -0
- package/dist/workspace/declaration.d.ts.map +1 -1
- package/dist/workspace/declaration.js +27 -1
- package/dist/workspace/declaration.schema.json +76 -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/identity-gate-rule.d.ts +37 -0
- package/dist/workspace/identity-gate-rule.d.ts.map +1 -1
- package/dist/workspace/identity-gate-rule.js +72 -7
- package/dist/workspace/identity.d.ts +12 -0
- package/dist/workspace/identity.d.ts.map +1 -1
- package/dist/workspace/identity.js +13 -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 +36 -7
- package/dist/workspace/intent.d.ts.map +1 -1
- package/dist/workspace/intent.js +192 -22
- package/dist/workspace/intent.schema.json +702 -6
- package/dist/workspace/ls.d.ts +4 -0
- package/dist/workspace/ls.d.ts.map +1 -1
- package/dist/workspace/ls.js +2 -0
- package/dist/workspace/ls.schema.json +3 -1
- package/dist/workspace/member-pipeline.d.ts +6 -0
- package/dist/workspace/member-pipeline.d.ts.map +1 -1
- package/dist/workspace/member-pipeline.js +6 -0
- 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/promotion-order.d.ts +41 -0
- package/dist/workspace/promotion-order.d.ts.map +1 -0
- package/dist/workspace/promotion-order.js +95 -0
- package/dist/workspace/reason-codes.d.ts +4 -0
- package/dist/workspace/reason-codes.d.ts.map +1 -1
- package/dist/workspace/reason-codes.js +7 -1
- 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 +81 -0
- package/dist/workspace/releases.d.ts.map +1 -0
- package/dist/workspace/releases.js +103 -0
- package/dist/workspace/releases.schema.json +513 -0
- package/dist/workspace/run-event.schema.json +295 -0
- package/dist/workspace/status-gates.d.ts +34 -1
- package/dist/workspace/status-gates.d.ts.map +1 -1
- package/dist/workspace/status-gates.js +31 -2
- package/dist/workspace/status-stewards.d.ts +4 -0
- package/dist/workspace/status-stewards.d.ts.map +1 -1
- package/dist/workspace/status-stewards.js +2 -0
- package/dist/workspace/status.d.ts +117 -0
- package/dist/workspace/status.d.ts.map +1 -1
- package/dist/workspace/status.js +218 -4
- package/dist/workspace/status.schema.json +268 -2
- package/dist/workspace/trust/ci-tag-statement.d.ts +102 -0
- package/dist/workspace/trust/ci-tag-statement.d.ts.map +1 -0
- package/dist/workspace/trust/ci-tag-statement.js +123 -0
- package/dist/workspace/trust/op-run-statement.d.ts +91 -0
- package/dist/workspace/trust/op-run-statement.d.ts.map +1 -0
- package/dist/workspace/trust/op-run-statement.js +143 -0
- package/dist/workspace/trust/rotation.d.ts +18 -2
- package/dist/workspace/trust/rotation.d.ts.map +1 -1
- package/dist/workspace/trust/rotation.js +65 -16
- package/dist/workspace/trust/seal.d.ts +11 -0
- package/dist/workspace/trust/seal.d.ts.map +1 -1
- package/dist/workspace/trust/seal.js +9 -0
- package/dist/workspace/trust/ssh-commit.d.ts.map +1 -1
- package/dist/workspace/trust/ssh-commit.js +10 -10
- package/dist/workspace/wip.d.ts.map +1 -1
- package/dist/workspace/wip.js +11 -3
- package/package.json +1 -1
- package/src/__golden__/wave-loop/fan-out-gated.json +8 -0
- package/src/__golden__/wave-loop/fan-out-no-members.json +4 -0
- package/src/__golden__/wave-loop/fan-out-only.json +6 -0
- package/src/__golden__/wave-loop/op-by-apply-hold.json +2 -0
- package/src/__golden__/wave-loop/op-cost-member.json +3 -0
- package/src/__golden__/wave-loop/op-held-on-before-apply.json +1 -0
- package/src/__golden__/wave-loop/op-held-on.json +2 -0
- package/src/__golden__/wave-loop/op-hooks-held.json +2 -0
- package/src/__golden__/wave-loop/op-hooks-hold-before-apply.json +2 -0
- package/src/__golden__/wave-loop/op-hooks-refused-at-base.json +3 -0
- package/src/__golden__/wave-loop/op-hooks-share.json +3 -0
- package/src/__golden__/wave-loop/op-per-run.json +7 -0
- package/src/__golden__/wave-loop/op-pr-review.json +7 -0
- package/src/__golden__/wave-loop/op-sealed.json +3 -0
- package/src/__golden__/wave-loop/op-spend.json +3 -0
- package/src/__golden__/wave-loop/op-wave-commands.json +7 -0
- package/src/__golden__/wave-loop/op-wide-waiting.json +4 -0
- package/src/build-params.test.ts +46 -0
- package/src/build-params.ts +55 -1
- package/src/change-set-graph.test.ts +72 -0
- package/src/change-set-graph.ts +141 -0
- package/src/change-set.ts +87 -6
- package/src/chant-version.ts +16 -0
- package/src/cli/build-params-cli.ts +22 -9
- package/src/cli/commands/build.ts +25 -11
- package/src/cli/commands/check-lexicon-docs.test.ts +51 -0
- package/src/cli/commands/check-lexicon-docs.ts +39 -2
- package/src/cli/commands/check-lexicon.ts +14 -2
- package/src/cli/commands/init-lexicon/templates/docs.ts +7 -6
- package/src/cli/commands/init-lexicon.test.ts +25 -0
- package/src/cli/commands/init-lexicon.ts +18 -8
- package/src/cli/handlers/approve-release.test.ts +84 -0
- package/src/cli/handlers/approve-revoked.test.ts +155 -0
- package/src/cli/handlers/approve.ts +65 -2
- package/src/cli/handlers/build.test.ts +67 -0
- package/src/cli/handlers/build.ts +46 -4
- package/src/cli/handlers/change-set.ts +49 -1
- package/src/cli/handlers/fan-out.test.ts +228 -1
- package/src/cli/handlers/fan-out.ts +53 -6
- 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/operator.test.ts +37 -0
- package/src/cli/handlers/pr.test.ts +341 -0
- package/src/cli/handlers/pr.ts +292 -47
- package/src/cli/handlers/promote.test.ts +669 -7
- package/src/cli/handlers/promote.ts +464 -29
- package/src/cli/handlers/release-implicit.e2e.test.ts +161 -0
- 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 +199 -0
- package/src/cli/handlers/release.ts +593 -0
- package/src/cli/handlers/run-auto-release.test.ts +80 -0
- package/src/cli/handlers/run-events-cmd.test.ts +92 -0
- package/src/cli/handlers/run-release.test.ts +55 -0
- package/src/cli/handlers/run.test.ts +30 -0
- package/src/cli/handlers/run.ts +243 -18
- package/src/cli/main.test.ts +8 -0
- package/src/cli/main.ts +143 -17
- package/src/cli/mcp/never-over-mcp.test.ts +2 -0
- package/src/cli/mcp/workspace-tools.ts +1 -1
- package/src/cli/parse-args.ts +56 -5
- package/src/cli/registry.ts +43 -5
- package/src/cli/run-events.ts +57 -0
- package/src/cli/version.ts +3 -13
- package/src/codegen/docs-in-site.test.ts +166 -0
- package/src/codegen/docs-in-site.ts +182 -0
- package/src/codegen/docs-site/AgentPrompt.astro +26 -1
- package/src/codegen/docs-types.ts +14 -1
- package/src/codegen/docs.ts +60 -7
- package/src/codegen/rehype-base-url.d.mts +3 -1
- package/src/codegen/rehype-base-url.mjs +15 -9
- package/src/codegen/rehype-base-url.test.ts +34 -0
- package/src/components/auto-release.test.ts +30 -0
- package/src/components/auto-release.ts +9 -1
- package/src/components/capability.ts +9 -0
- package/src/components/cli-support.test.ts +82 -0
- package/src/components/cli-support.ts +16 -9
- package/src/components/driver.test.ts +24 -0
- package/src/components/driver.ts +165 -56
- 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 +104 -35
- package/src/components/fan-out.ts +4 -0
- package/src/components/pr-pipeline.ts +35 -4
- package/src/components/pr-run.ts +30 -1
- package/src/components/promote-order.test.ts +90 -0
- package/src/components/promote-order.ts +75 -0
- package/src/components/promote.test.ts +10 -1
- package/src/components/promote.ts +94 -3
- package/src/components/release-compile.test.ts +147 -0
- package/src/components/release-compile.ts +459 -0
- package/src/components/release-gate.test.ts +215 -0
- package/src/components/release-gate.ts +355 -0
- package/src/components/release-promote.test.ts +159 -0
- package/src/components/release-promote.ts +232 -0
- package/src/components/run-progress.ts +7 -0
- package/src/components/wave-plan.ts +16 -3
- package/src/config.ts +15 -1
- package/src/flag-params.test.ts +144 -0
- package/src/flag-params.ts +134 -0
- package/src/index.ts +2 -0
- package/src/lifecycle/__fixtures__/publish-fakes.ts +351 -0
- package/src/lifecycle/change-set-store.test.ts +217 -0
- package/src/lifecycle/change-set-store.ts +113 -0
- package/src/lifecycle/commit-sha.ts +23 -0
- package/src/lifecycle/delivery-metrics.ts +263 -0
- package/src/lifecycle/deploy-outcome.ts +147 -0
- package/src/lifecycle/gate-change-set.e2e.test.ts +122 -0
- package/src/lifecycle/gate-change-set.ts +164 -0
- package/src/lifecycle/gate-ledger.test.ts +33 -0
- package/src/lifecycle/gate-ledger.ts +68 -3
- 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-signed.test.ts +180 -0
- package/src/lifecycle/release-cut.test.ts +483 -0
- package/src/lifecycle/release-cut.ts +503 -0
- 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.test.ts +14 -0
- package/src/lifecycle/release-ledger.ts +85 -17
- 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 +434 -0
- 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.test.ts +10 -0
- package/src/lifecycle/run-ledger.ts +6 -0
- package/src/op/activities/change-coverage.ts +4 -1
- package/src/op/activities/source-release.ts +8 -3
- package/src/op/activities/source-rollback.ts +8 -4
- package/src/op/commit-run-gate-deploy-join.test.ts +117 -0
- package/src/op/gate-name.ts +13 -3
- package/src/op/gate-release.test.ts +126 -0
- package/src/op/gate-run-locator.test.ts +110 -0
- package/src/op/gate-run-locator.ts +35 -0
- package/src/op/gate.ts +88 -6
- package/src/op/local-executor.ts +207 -52
- package/src/op/op-waves-run.ts +4 -0
- package/src/op/run-events.test.ts +166 -0
- package/src/op/run-live.ts +1 -1
- package/src/op/runtime.ts +39 -0
- package/src/op/runtimes/local.test.ts +16 -0
- package/src/op/runtimes/local.ts +9 -0
- package/src/plan-summary.test.ts +20 -0
- package/src/plan-summary.ts +8 -1
- package/src/point-decision.ts +12 -2
- package/src/pr-loop.ts +25 -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.test.ts +144 -0
- package/src/run-event-store.ts +273 -0
- package/src/run-event-stream.test.ts +175 -0
- package/src/run-event-stream.ts +309 -0
- package/src/run-event.test.ts +277 -0
- package/src/run-event.ts +471 -0
- package/src/wave-loop-golden.test.ts +9 -0
- 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/__fixtures__/run-event-check.ts +58 -0
- package/src/workspace/ancestry-index.test.ts +93 -0
- package/src/workspace/change-set-show.schema.json +102 -0
- package/src/workspace/change-set-show.ts +72 -0
- package/src/workspace/change-set.schema.json +32 -1
- package/src/workspace/changes-cli.ts +10 -1
- package/src/workspace/changes.schema.json +135 -0
- package/src/workspace/changes.test.ts +1 -1
- package/src/workspace/changes.ts +84 -2
- 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-cli.ts +75 -13
- package/src/workspace/ci-green-forge.ts +24 -4
- package/src/workspace/ci-green-runs.test.ts +242 -0
- package/src/workspace/ci-green-signed.test.ts +302 -0
- package/src/workspace/ci-green-workflow.test.ts +16 -0
- package/src/workspace/ci-green-workflow.ts +12 -0
- package/src/workspace/ci-green.test.ts +131 -2
- package/src/workspace/ci-green.ts +635 -42
- package/src/workspace/ci-last-green.schema.json +32 -2
- package/src/workspace/ci-list.schema.json +525 -0
- package/src/workspace/commit-links.test.ts +279 -0
- package/src/workspace/commit-links.ts +183 -0
- package/src/workspace/declaration.schema.json +76 -0
- package/src/workspace/declaration.test.ts +28 -0
- package/src/workspace/declaration.ts +60 -2
- 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/identity-gate-rule.ts +91 -7
- package/src/workspace/identity.ts +14 -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 +196 -26
- package/src/workspace/ls.schema.json +3 -1
- package/src/workspace/ls.ts +6 -0
- package/src/workspace/member-pipeline.test.ts +17 -0
- package/src/workspace/member-pipeline.ts +9 -0
- 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/promotion-order.ts +97 -0
- package/src/workspace/read-contract.e2e.test.ts +5 -1
- package/src/workspace/reason-codes.test.ts +7 -1
- package/src/workspace/reason-codes.ts +7 -1
- 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 +513 -0
- package/src/workspace/releases.test.ts +108 -0
- package/src/workspace/releases.ts +133 -0
- package/src/workspace/run-event.schema.json +295 -0
- package/src/workspace/status-contract.test.ts +81 -1
- package/src/workspace/status-gates.ts +64 -1
- package/src/workspace/status-mixed.test.ts +152 -0
- package/src/workspace/status-revoked.test.ts +153 -0
- package/src/workspace/status-stewards.ts +6 -0
- package/src/workspace/status.schema.json +268 -2
- package/src/workspace/status.ts +334 -4
- package/src/workspace/trust/ci-tag-statement.ts +151 -0
- package/src/workspace/trust/op-run-statement.ts +148 -0
- package/src/workspace/trust/rotation.ts +61 -14
- package/src/workspace/trust/seal.ts +10 -0
- package/src/workspace/trust/ssh-commit.ts +10 -9
- package/src/workspace/wip.ts +11 -2
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/astro.config.mjs +0 -14
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/package.json +0 -16
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/src/content/docs/index.mdx +0 -8
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/src/content.config.ts +0 -15
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/tsconfig.json +0 -10
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feature flags as workspace records (#4024, decided in #4016).
|
|
3
|
+
*
|
|
4
|
+
* A flag is a record of a kind with a `flag` block (`records.ts`). It names a
|
|
5
|
+
* member, one of that member's declared build-time parameters, an owner, the
|
|
6
|
+
* work item the flag hides and a value per environment. The member's build
|
|
7
|
+
* reads it as that parameter (`../flag-params.ts`), so turning a flag on in
|
|
8
|
+
* an environment is a commit that changes the record, and the release cut
|
|
9
|
+
* from that commit carries the new value as a `params` entry whose `source`
|
|
10
|
+
* is `flag:<id>` (ws-104).
|
|
11
|
+
*
|
|
12
|
+
* This module and `./flags-read.ts` do three things:
|
|
13
|
+
*
|
|
14
|
+
* - {@link applyFlags}: on a `records` read of a flag kind, gives each record
|
|
15
|
+
* its work item with that item's state, the decisions the item implements,
|
|
16
|
+
* and whether the flag is due for removal, with the warnings
|
|
17
|
+
* `flag-work-unknown` and `flag-stale`.
|
|
18
|
+
* - `readWorkspaceFlags` (`./flags-read.ts`): every flag of every flag kind
|
|
19
|
+
* the declaration names, for `workspace status` (`featureFlags`) and the
|
|
20
|
+
* build.
|
|
21
|
+
* - `memberFlagBindings` (`./flags-read.ts`): the flags of the member holding
|
|
22
|
+
* a directory, by parameter, for one environment.
|
|
23
|
+
*
|
|
24
|
+
* The readers live apart so that `records.ts`, which loads this module for a
|
|
25
|
+
* flag kind, never reaches `records-cli.ts` and what it imports.
|
|
26
|
+
*
|
|
27
|
+
* A flag is due for removal when its work item implements at least one
|
|
28
|
+
* decision and every decision it implements is confirmed: in one of its
|
|
29
|
+
* kind's closed states and superseded by nothing. For chant's decision kind
|
|
30
|
+
* that is `ratified` (a superseded decision has a superseder). The work is
|
|
31
|
+
* then settled, and the flag that hid it is dead weight.
|
|
32
|
+
*/
|
|
33
|
+
import { type LoadedRecordKind, type ReadRecordsOptions, type RecordEntry } from "./records.js";
|
|
34
|
+
import type { WorkLink } from "./work.js";
|
|
35
|
+
/** Why a flag record carries a warning. Closed, like the record warning codes. */
|
|
36
|
+
export declare const FLAG_WARNING_CODES: readonly ["flag-work-unknown", "flag-stale"];
|
|
37
|
+
export type FlagWarningCode = (typeof FLAG_WARNING_CODES)[number];
|
|
38
|
+
/** A flag's value in one environment: what a build-time parameter can hold. */
|
|
39
|
+
export type FlagValue = string | number | boolean;
|
|
40
|
+
/** A decision a flag's work item implements, with whether it is confirmed. */
|
|
41
|
+
export interface FlagDecision extends WorkLink {
|
|
42
|
+
/** In one of its kind's closed states and superseded by nothing. */
|
|
43
|
+
confirmed: boolean;
|
|
44
|
+
}
|
|
45
|
+
/** What a read of a flag kind adds to each record (#4024). */
|
|
46
|
+
export interface FlagState {
|
|
47
|
+
/** The work item the flag hides, with its state, or null when the record names none. The state is null when no record has the id. */
|
|
48
|
+
work: WorkLink | null;
|
|
49
|
+
/** Each decision the work item implements, with its state. Empty when the item is unknown or implements none. */
|
|
50
|
+
implements: FlagDecision[];
|
|
51
|
+
/** True when the work item implements at least one decision and every one is confirmed: the flag is due for removal. */
|
|
52
|
+
stale: boolean;
|
|
53
|
+
}
|
|
54
|
+
/** A flag as `workspace status` and the build read it. */
|
|
55
|
+
export interface WorkspaceFlag {
|
|
56
|
+
/** The flag's name, its record's id. */
|
|
57
|
+
id: string;
|
|
58
|
+
/** The kind file from the workspace root. */
|
|
59
|
+
kind: string;
|
|
60
|
+
/** The record file from the workspace root, with / separators. */
|
|
61
|
+
path: string;
|
|
62
|
+
member: string;
|
|
63
|
+
param: string;
|
|
64
|
+
owner: string;
|
|
65
|
+
/** The value per environment, as the record writes it, in key order. */
|
|
66
|
+
values: Record<string, FlagValue>;
|
|
67
|
+
work: WorkLink | null;
|
|
68
|
+
implements: FlagDecision[];
|
|
69
|
+
stale: boolean;
|
|
70
|
+
}
|
|
71
|
+
/** A flag record that is not valid, so no build trusts it. */
|
|
72
|
+
export interface InvalidFlag {
|
|
73
|
+
kind: string;
|
|
74
|
+
path: string;
|
|
75
|
+
/** The member the record names, or null when it names none that can be read. */
|
|
76
|
+
member: string | null;
|
|
77
|
+
message: string;
|
|
78
|
+
}
|
|
79
|
+
/** Every flag a workspace's declared flag kinds hold. */
|
|
80
|
+
export interface WorkspaceFlags {
|
|
81
|
+
flags: WorkspaceFlag[];
|
|
82
|
+
invalid: InvalidFlag[];
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Whether a decision is confirmed: in one of its kind's `closed` states and
|
|
86
|
+
* superseded by nothing. An unknown decision is not. The overlap report
|
|
87
|
+
* (#4025) shares it: a work item is in flight while any decision it
|
|
88
|
+
* implements is not confirmed.
|
|
89
|
+
*/
|
|
90
|
+
export declare function decisionConfirmed(decision: {
|
|
91
|
+
state: string | null;
|
|
92
|
+
supersededBy: string | null;
|
|
93
|
+
} | undefined, closed: ReadonlySet<string>): boolean;
|
|
94
|
+
/**
|
|
95
|
+
* Give each record of a flag kind its {@link FlagState} and warnings, in
|
|
96
|
+
* place. Throws a `RecordReadError` when the work kind it names can't be read
|
|
97
|
+
* or is not a work kind.
|
|
98
|
+
*/
|
|
99
|
+
export declare function applyFlags(loaded: LoadedRecordKind, entries: RecordEntry[], options: ReadRecordsOptions): Promise<void>;
|
|
100
|
+
//# sourceMappingURL=flags.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flags.d.ts","sourceRoot":"","sources":["../../src/workspace/flags.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAIH,OAAO,EAAgD,KAAK,gBAAgB,EAAE,KAAK,kBAAkB,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AAC3I,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAEvC,kFAAkF;AAClF,eAAO,MAAM,kBAAkB,8CAKW,CAAC;AAC3C,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAElE,+EAA+E;AAC/E,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAElD,8EAA8E;AAC9E,MAAM,WAAW,YAAa,SAAQ,QAAQ;IAC5C,oEAAoE;IACpE,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,8DAA8D;AAC9D,MAAM,WAAW,SAAS;IACxB,qIAAqI;IACrI,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IACtB,iHAAiH;IACjH,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B,wHAAwH;IACxH,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,0DAA0D;AAC1D,MAAM,WAAW,aAAa;IAC5B,wCAAwC;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAClC,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,8DAA8D;AAC9D,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,gFAAgF;IAChF,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,yDAAyD;AACzD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AAID;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE;IAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,OAAO,CAEnJ;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuC7H"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feature flags as workspace records (#4024, decided in #4016).
|
|
3
|
+
*
|
|
4
|
+
* A flag is a record of a kind with a `flag` block (`records.ts`). It names a
|
|
5
|
+
* member, one of that member's declared build-time parameters, an owner, the
|
|
6
|
+
* work item the flag hides and a value per environment. The member's build
|
|
7
|
+
* reads it as that parameter (`../flag-params.ts`), so turning a flag on in
|
|
8
|
+
* an environment is a commit that changes the record, and the release cut
|
|
9
|
+
* from that commit carries the new value as a `params` entry whose `source`
|
|
10
|
+
* is `flag:<id>` (ws-104).
|
|
11
|
+
*
|
|
12
|
+
* This module and `./flags-read.ts` do three things:
|
|
13
|
+
*
|
|
14
|
+
* - {@link applyFlags}: on a `records` read of a flag kind, gives each record
|
|
15
|
+
* its work item with that item's state, the decisions the item implements,
|
|
16
|
+
* and whether the flag is due for removal, with the warnings
|
|
17
|
+
* `flag-work-unknown` and `flag-stale`.
|
|
18
|
+
* - `readWorkspaceFlags` (`./flags-read.ts`): every flag of every flag kind
|
|
19
|
+
* the declaration names, for `workspace status` (`featureFlags`) and the
|
|
20
|
+
* build.
|
|
21
|
+
* - `memberFlagBindings` (`./flags-read.ts`): the flags of the member holding
|
|
22
|
+
* a directory, by parameter, for one environment.
|
|
23
|
+
*
|
|
24
|
+
* The readers live apart so that `records.ts`, which loads this module for a
|
|
25
|
+
* flag kind, never reaches `records-cli.ts` and what it imports.
|
|
26
|
+
*
|
|
27
|
+
* A flag is due for removal when its work item implements at least one
|
|
28
|
+
* decision and every decision it implements is confirmed: in one of its
|
|
29
|
+
* kind's closed states and superseded by nothing. For chant's decision kind
|
|
30
|
+
* that is `ratified` (a superseded decision has a superseder). The work is
|
|
31
|
+
* then settled, and the flag that hid it is dead weight.
|
|
32
|
+
*/
|
|
33
|
+
import { dirname } from "node:path";
|
|
34
|
+
import { loadRecordKind, readRecords, RecordReadError } from "./records.js";
|
|
35
|
+
/** Why a flag record carries a warning. Closed, like the record warning codes. */
|
|
36
|
+
export const FLAG_WARNING_CODES = [
|
|
37
|
+
/** The flag names a work item no record of its kind's work kind has. */
|
|
38
|
+
"flag-work-unknown",
|
|
39
|
+
/** Every decision the flag's work item implements is confirmed, so the flag is due for removal. `check` reports it (WSP118). */
|
|
40
|
+
"flag-stale",
|
|
41
|
+
];
|
|
42
|
+
const str = (v) => (typeof v === "string" && v !== "" ? v : null);
|
|
43
|
+
/**
|
|
44
|
+
* Whether a decision is confirmed: in one of its kind's `closed` states and
|
|
45
|
+
* superseded by nothing. An unknown decision is not. The overlap report
|
|
46
|
+
* (#4025) shares it: a work item is in flight while any decision it
|
|
47
|
+
* implements is not confirmed.
|
|
48
|
+
*/
|
|
49
|
+
export function decisionConfirmed(decision, closed) {
|
|
50
|
+
return decision !== undefined && decision.state !== null && closed.has(decision.state) && decision.supersededBy === null;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Give each record of a flag kind its {@link FlagState} and warnings, in
|
|
54
|
+
* place. Throws a `RecordReadError` when the work kind it names can't be read
|
|
55
|
+
* or is not a work kind.
|
|
56
|
+
*/
|
|
57
|
+
export async function applyFlags(loaded, entries, options) {
|
|
58
|
+
const flag = loaded.kind.flag;
|
|
59
|
+
const workKind = await loadRecordKind(flag.work.kind, dirname(loaded.file));
|
|
60
|
+
if (!workKind.kind.work) {
|
|
61
|
+
throw new RecordReadError("kind-invalid", `flag kind ${loaded.kind.name} names ${flag.work.kind} as its work kind, and that kind has no work block`);
|
|
62
|
+
}
|
|
63
|
+
const decisionKind = await loadRecordKind(workKind.kind.work.decisions, dirname(workKind.file));
|
|
64
|
+
const read = await readRecords(workKind, { root: options.root, source: options.source });
|
|
65
|
+
const items = new Map();
|
|
66
|
+
for (const r of read.records)
|
|
67
|
+
if (r.id !== null && !items.has(r.id))
|
|
68
|
+
items.set(r.id, r);
|
|
69
|
+
const decisions = new Map((read.decisions ?? []).map((d) => [d.id, d]));
|
|
70
|
+
const closed = new Set(decisionKind.kind.closedStates ?? []);
|
|
71
|
+
for (const e of entries) {
|
|
72
|
+
if (e.data === null)
|
|
73
|
+
continue;
|
|
74
|
+
const named = str(e.data[flag.work.field]);
|
|
75
|
+
if (named === null) {
|
|
76
|
+
e.flag = { work: null, implements: [], stale: false };
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
const item = items.get(named);
|
|
80
|
+
if (!item) {
|
|
81
|
+
e.flag = { work: { id: named, state: null }, implements: [], stale: false };
|
|
82
|
+
e.warnings.push({ code: "flag-work-unknown", message: `hides the work item ${named}, which no record in ${flag.work.kind} has` });
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const implementsList = (item.implements ?? []).map((d) => {
|
|
86
|
+
const decision = decisions.get(d.id);
|
|
87
|
+
return { ...d, confirmed: decisionConfirmed(decision, closed) };
|
|
88
|
+
});
|
|
89
|
+
const stale = implementsList.length > 0 && implementsList.every((d) => d.confirmed);
|
|
90
|
+
e.flag = { work: { id: named, state: item.state }, implements: implementsList, stale };
|
|
91
|
+
if (stale) {
|
|
92
|
+
e.warnings.push({
|
|
93
|
+
code: "flag-stale",
|
|
94
|
+
message: `is due for removal: its work item ${named} implements ${implementsList.map((d) => `${d.id} (${d.state})`).join(", ")}, and every one is confirmed`,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -51,7 +51,7 @@ export const GRAPH_OUTPUT_SCHEMA_ID = "https://intentius.io/chant/schemas/worksp
|
|
|
51
51
|
export const GRAPH_ERROR_CODES = [...WORKSPACE_ERROR_CODES, "live-at-revision"];
|
|
52
52
|
/** Why `--live` and `--at` don't go together (#2875). */
|
|
53
53
|
const LIVE_AT_REVISION = "--live reads the account as it stands now, and --at reads the source at a revision; chant workspace graph takes one of them";
|
|
54
|
-
const USAGE = "chant workspace graph [dir] [--at <rev>] [--member <name>] [--kind <kind file>] [-o <file>] [--env <env>] [--live [--overlay] [--traffic <level>]] [--no-cache] [--dry-run] | chant workspace graph --composites [--at <rev>] [--member <name>] [-o <file>] | chant workspace graph --intent <path[:start-end]|path#symbol> [--at <rev>] [--kind <kind file>...] [--follow-squash] [--json]";
|
|
54
|
+
const USAGE = "chant workspace graph [dir] [--at <rev>] [--member <name>] [--kind <kind file>] [-o <file>] [--env <env>] [--live [--overlay] [--traffic <level>]] [--no-cache] [--dry-run] | chant workspace graph --composites [--at <rev>] [--member <name>] [-o <file>] | chant workspace graph --intent <path[:start-end]|path#symbol|member/node|sha> [--at <rev>] [--kind <kind file>...] [--follow-squash] [--json]";
|
|
55
55
|
/** The command line a member runs for its component graph (#2662). */
|
|
56
56
|
export function componentGraphArgv(args) {
|
|
57
57
|
return ["graph", ".", "--components", "--format", "ir", ...(args.env ? ["--env", args.env] : [])];
|
|
@@ -62,4 +62,41 @@ export declare function grantedClasses(classes: readonly ClassGrant[], roles: Re
|
|
|
62
62
|
* know lets nothing through.
|
|
63
63
|
*/
|
|
64
64
|
export declare function admitApprover(rule: GateAdmissionRule, a: SealedGateApproval): string | null;
|
|
65
|
+
/** The gate whose `identity.gates` entry says who may cut a release (#4031). */
|
|
66
|
+
export declare const RELEASE_GATE = "release";
|
|
67
|
+
/** The ssh signature namespace of a release cut's signature (#4031), so no other signature can stand in for one. */
|
|
68
|
+
export declare const RELEASE_SEAL_NAMESPACE = "chant-release";
|
|
69
|
+
/** A cut line's fields its signature covers (#4031), and the signature. */
|
|
70
|
+
export interface SignedReleaseCut {
|
|
71
|
+
releaseDigest: string;
|
|
72
|
+
label: string | null;
|
|
73
|
+
actor: string;
|
|
74
|
+
timestamp: string;
|
|
75
|
+
/** The armored ssh signature, or null for an unsigned cut. */
|
|
76
|
+
signature: string | null;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The bytes a release cut's signature signs (#4031): the release digest,
|
|
80
|
+
* the label (empty for none), the actor who cut it and the cut's time,
|
|
81
|
+
* joined by LF with no final newline.
|
|
82
|
+
*/
|
|
83
|
+
export declare function releaseSealPayload(cut: Omit<SignedReleaseCut, "signature">): Buffer;
|
|
84
|
+
/**
|
|
85
|
+
* Why `cut` may not be made under the `release` gate's rule, or null when
|
|
86
|
+
* it may (#4031): its signature verifies for its actor against the signers
|
|
87
|
+
* at base and, when the gate names a class, the role grants at base put the
|
|
88
|
+
* actor in it. The same rule {@link admitApprover} applies to an approval,
|
|
89
|
+
* over the cut's own signed bytes.
|
|
90
|
+
*/
|
|
91
|
+
export declare function admitReleaseCut(rule: GateAdmissionRule, cut: SignedReleaseCut): string | null;
|
|
92
|
+
/** Whether a cut's signature verifies, as `release list` and `workspace status` report it (#4031). */
|
|
93
|
+
export interface ReleaseSignatureCheck {
|
|
94
|
+
/** `verified`: it verifies for the actor, who is in the release gate's class when it names one. `unsigned`: the cut has none. `unverified`: it does not, and `reason` says why. */
|
|
95
|
+
status: "verified" | "unsigned" | "unverified";
|
|
96
|
+
/** The fingerprint of the key in the signature, or null for an unsigned cut or one that can't be read. */
|
|
97
|
+
key: string | null;
|
|
98
|
+
reason: string;
|
|
99
|
+
}
|
|
100
|
+
/** Judge a stored cut's signature against `rule`, read at base. A rule with no class checks the signature alone. */
|
|
101
|
+
export declare function checkReleaseSignature(rule: GateAdmissionRule, cut: SignedReleaseCut): ReleaseSignatureCheck;
|
|
65
102
|
//# sourceMappingURL=identity-gate-rule.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity-gate-rule.d.ts","sourceRoot":"","sources":["../../src/workspace/identity-gate-rule.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"identity-gate-rule.d.ts","sourceRoot":"","sources":["../../src/workspace/identity-gate-rule.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* The module imports node:crypto through `./trust/gate-seal.ts` and nothing
|
|
14
14
|
* else: no zod, no ajv, no package loading, so it bundles small.
|
|
15
15
|
*/
|
|
16
|
-
import { GATE_SEAL_NAMESPACE, gateSealPayload, namespaceAllowed, verifySshSignatureWith } from "./trust/gate-seal.js";
|
|
16
|
+
import { GATE_SEAL_NAMESPACE, gateSealPayload, namespaceAllowed, sshKeyFingerprint, sshSignatureKey, verifySshSignatureWith } from "./trust/gate-seal.js";
|
|
17
17
|
/** The core classes, in the order a principal's roles are tried; `human` holds no role and is the rest. */
|
|
18
18
|
export const CORE_PRINCIPAL_CLASSES = ["human", "agent", "runner", "service"];
|
|
19
19
|
export const CORE_CLASSES = [
|
|
@@ -39,20 +39,85 @@ export function grantedClasses(classes, roles, principal) {
|
|
|
39
39
|
*/
|
|
40
40
|
export function admitApprover(rule, a) {
|
|
41
41
|
const { gate, signers } = rule;
|
|
42
|
-
const
|
|
43
|
-
if (
|
|
44
|
-
return
|
|
45
|
-
}
|
|
42
|
+
const unknown = unknownClassRefusal(rule, "approval");
|
|
43
|
+
if (unknown !== null)
|
|
44
|
+
return unknown;
|
|
46
45
|
if (!signers.active)
|
|
47
46
|
return `gate ${gate} needs a signed approval, and there is no signers file (${signers.signersPath}) at base to check one against`;
|
|
48
47
|
const seal = sealRefusal(gate, signers, a);
|
|
49
48
|
if (seal !== null)
|
|
50
49
|
return seal;
|
|
50
|
+
return classRefusal(rule, a.resolvedBy);
|
|
51
|
+
}
|
|
52
|
+
/** Why no signature can show a principal is in the rule's class: the class is one the rule does not know. Null otherwise. */
|
|
53
|
+
function unknownClassRefusal(rule, what) {
|
|
54
|
+
const want = rule.class;
|
|
55
|
+
if (want === null || rule.classes.some((c) => c.name === want))
|
|
56
|
+
return null;
|
|
57
|
+
return `identity.gates.${rule.gate} names the class ${want}, which ${rule.unknownClass ?? "no pinned package supplies"}, so no ${what} can show it is in that class (known classes: ${rule.classes.map((c) => c.name).join(", ")})`;
|
|
58
|
+
}
|
|
59
|
+
/** Why `principal` is not in the rule's class, or null when it is or the rule names none. */
|
|
60
|
+
function classRefusal(rule, principal) {
|
|
61
|
+
const want = rule.class;
|
|
51
62
|
if (want === null)
|
|
52
63
|
return null;
|
|
53
|
-
const granted = grantedClasses(rule.classes, rule.roles,
|
|
64
|
+
const granted = grantedClasses(rule.classes, rule.roles, principal);
|
|
54
65
|
const inClass = want === "human" ? granted.length === 0 : granted.includes(want);
|
|
55
|
-
return inClass ? null : `${
|
|
66
|
+
return inClass ? null : `${principal} is not in the class ${want} that gate ${rule.gate} needs: no role grant at base puts them there`;
|
|
67
|
+
}
|
|
68
|
+
// ── release cuts (#4031) ─────────────────────────────────────────────────
|
|
69
|
+
/** The gate whose `identity.gates` entry says who may cut a release (#4031). */
|
|
70
|
+
export const RELEASE_GATE = "release";
|
|
71
|
+
/** The ssh signature namespace of a release cut's signature (#4031), so no other signature can stand in for one. */
|
|
72
|
+
export const RELEASE_SEAL_NAMESPACE = "chant-release";
|
|
73
|
+
/**
|
|
74
|
+
* The bytes a release cut's signature signs (#4031): the release digest,
|
|
75
|
+
* the label (empty for none), the actor who cut it and the cut's time,
|
|
76
|
+
* joined by LF with no final newline.
|
|
77
|
+
*/
|
|
78
|
+
export function releaseSealPayload(cut) {
|
|
79
|
+
return Buffer.from(`${cut.releaseDigest}\n${cut.label ?? ""}\n${cut.actor}\n${cut.timestamp}`, "utf-8");
|
|
80
|
+
}
|
|
81
|
+
/** Why the cut's signature does not verify for its actor against the signers at base, or null when it does. */
|
|
82
|
+
function releaseSignatureRefusal(signers, cut) {
|
|
83
|
+
if (cut.signature === null)
|
|
84
|
+
return `the cut by ${cut.actor} is not signed`;
|
|
85
|
+
if (!signers.active)
|
|
86
|
+
return `there is no signers file (${signers.signersPath}) at base to check the cut's signature against`;
|
|
87
|
+
const where = `${signers.signersPath} at base`;
|
|
88
|
+
const listed = signers.signers.filter((s) => normalise(s.principal) === normalise(cut.actor));
|
|
89
|
+
if (listed.length === 0)
|
|
90
|
+
return `${cut.actor} has no key in ${where}, so the cut's signature can't count`;
|
|
91
|
+
const keys = listed.filter((s) => namespaceAllowed(s.namespaces, RELEASE_SEAL_NAMESPACE)).map((s) => Buffer.from(s.key.split(" ")[1] ?? "", "base64"));
|
|
92
|
+
const r = verifySshSignatureWith(cut.signature, releaseSealPayload(cut), RELEASE_SEAL_NAMESPACE, keys);
|
|
93
|
+
return r.ok ? null : `the cut's signature does not verify for ${cut.actor} against ${where}: ${r.reason}`;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Why `cut` may not be made under the `release` gate's rule, or null when
|
|
97
|
+
* it may (#4031): its signature verifies for its actor against the signers
|
|
98
|
+
* at base and, when the gate names a class, the role grants at base put the
|
|
99
|
+
* actor in it. The same rule {@link admitApprover} applies to an approval,
|
|
100
|
+
* over the cut's own signed bytes.
|
|
101
|
+
*/
|
|
102
|
+
export function admitReleaseCut(rule, cut) {
|
|
103
|
+
const unknown = unknownClassRefusal(rule, "cut");
|
|
104
|
+
if (unknown !== null)
|
|
105
|
+
return unknown;
|
|
106
|
+
const seal = releaseSignatureRefusal(rule.signers, cut);
|
|
107
|
+
if (seal !== null)
|
|
108
|
+
return `${seal}; identity.gates.${rule.gate} needs a release cut signed with chant release cut --sign`;
|
|
109
|
+
return classRefusal(rule, cut.actor);
|
|
110
|
+
}
|
|
111
|
+
/** Judge a stored cut's signature against `rule`, read at base. A rule with no class checks the signature alone. */
|
|
112
|
+
export function checkReleaseSignature(rule, cut) {
|
|
113
|
+
if (cut.signature === null)
|
|
114
|
+
return { status: "unsigned", key: null, reason: "the cut carries no signature" };
|
|
115
|
+
const blob = sshSignatureKey(cut.signature);
|
|
116
|
+
const key = blob ? sshKeyFingerprint(blob) : null;
|
|
117
|
+
const why = unknownClassRefusal(rule, "cut") ?? releaseSignatureRefusal(rule.signers, cut) ?? classRefusal(rule, cut.actor);
|
|
118
|
+
if (why !== null)
|
|
119
|
+
return { status: "unverified", key, reason: why };
|
|
120
|
+
return { status: "verified", key, reason: `signed by ${cut.actor}${rule.class !== null ? `, in the class ${rule.class}` : ""}` };
|
|
56
121
|
}
|
|
57
122
|
/** The seal step, worded as `checkGateSeal` (`./trust/seal.ts`) words it against an active signers file at base. */
|
|
58
123
|
function sealRefusal(gate, signers, a) {
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
* sealed by a signer, from a class when it names one.
|
|
26
26
|
*/
|
|
27
27
|
import type { Declaration, SignedGate } from "./declaration.js";
|
|
28
|
+
import { type GateAdmissionRule } from "./identity-gate-rule.js";
|
|
28
29
|
import { type ClassRegistry } from "./principal-classes.js";
|
|
29
30
|
import type { TrustPolicy } from "./trust/policy.js";
|
|
30
31
|
import type { SealedGateApproval } from "./trust/gate-seal.js";
|
|
@@ -103,6 +104,17 @@ export interface GateRuleSource extends IdentitySource {
|
|
|
103
104
|
* the one at base, never a returned work's copy.
|
|
104
105
|
*/
|
|
105
106
|
export declare function gateAdmissionFrom(source: GateRuleSource, gate: string): GateAdmission | null;
|
|
107
|
+
/**
|
|
108
|
+
* The rule a release cut is judged by (#4031): the declaration's
|
|
109
|
+
* `identity.gates.release` entry with its class, read at base, or, when the
|
|
110
|
+
* declaration names no `release` gate, a rule with no class, which checks a
|
|
111
|
+
* cut's signature alone. `requirement` is null in that case, and a cut may
|
|
112
|
+
* then be made unsigned.
|
|
113
|
+
*/
|
|
114
|
+
export declare function releaseRuleFrom(source: GateRuleSource): {
|
|
115
|
+
requirement: SignedGate | null;
|
|
116
|
+
rule: GateAdmissionRule;
|
|
117
|
+
};
|
|
106
118
|
/**
|
|
107
119
|
* The rule for `gate` in the workspace holding `cwd`, read at base (the
|
|
108
120
|
* target branch tip), or null when there is no declaration or it names none.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/workspace/identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/workspace/identity.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
* write, and `gates.<gate>` lets a gate of that name pass only on an approval
|
|
25
25
|
* sealed by a signer, from a class when it names one.
|
|
26
26
|
*/
|
|
27
|
-
import { admitApprover } from "./identity-gate-rule.js";
|
|
27
|
+
import { admitApprover, RELEASE_GATE } from "./identity-gate-rule.js";
|
|
28
28
|
import { classesOf, coreClassRegistry, roleGrants } from "./principal-classes.js";
|
|
29
29
|
import { normalisePrincipal } from "./records.js";
|
|
30
30
|
import { scopeSource } from "./write-scope.js";
|
|
@@ -114,6 +114,18 @@ export function gateAdmissionFrom(source, gate) {
|
|
|
114
114
|
const rule = { gate, class: requirement.class, signers: policy, roles: roleGrants(policy), classes: classes.all() };
|
|
115
115
|
return { requirement, refuses: (a) => admitApprover(rule, a) };
|
|
116
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* The rule a release cut is judged by (#4031): the declaration's
|
|
119
|
+
* `identity.gates.release` entry with its class, read at base, or, when the
|
|
120
|
+
* declaration names no `release` gate, a rule with no class, which checks a
|
|
121
|
+
* cut's signature alone. `requirement` is null in that case, and a cut may
|
|
122
|
+
* then be made unsigned.
|
|
123
|
+
*/
|
|
124
|
+
export function releaseRuleFrom(source) {
|
|
125
|
+
const requirement = source.declaration?.identity?.gates[RELEASE_GATE] ?? null;
|
|
126
|
+
const { policy, classes } = source;
|
|
127
|
+
return { requirement, rule: { gate: RELEASE_GATE, class: requirement?.class ?? null, signers: policy, roles: roleGrants(policy), classes: classes.all() } };
|
|
128
|
+
}
|
|
117
129
|
/**
|
|
118
130
|
* The rule for `gate` in the workspace holding `cwd`, read at base (the
|
|
119
131
|
* target branch tip), or null when there is no declaration or it names none.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `chant workspace graph --intent <path[:start-end]|path#symbol> [--at <rev>] [--kind <kind file>...] [--follow-squash] [--json]`
|
|
2
|
+
* `chant workspace graph --intent <path[:start-end]|path#symbol|member/node|sha> [--at <rev>] [--kind <kind file>...] [--follow-squash] [--json]`
|
|
3
3
|
* (#2651, #3034): the intent graph over one region (`intent.ts`), printed as JSON
|
|
4
4
|
* with `--json` or as a walk, one line per node, in the order of #2650
|
|
5
5
|
* section B: the region, its decisions, their artifacts, the commits, and the
|
|
@@ -7,10 +7,13 @@
|
|
|
7
7
|
* the decisions governing it, most relevant first. Under each decision come the commits made inside its window, and
|
|
8
8
|
* when any of them is not the decision's own work, the question #2650 B puts
|
|
9
9
|
* to the person about it (#2656). Without `--kind`, the walk reads every
|
|
10
|
-
* record kind the declaration names (#2680).
|
|
10
|
+
* record kind the declaration names (#2680). Last comes the why chain (#4023):
|
|
11
|
+
* each commit's work item, ci tag and release, and each release's gates and
|
|
12
|
+
* deploys.
|
|
11
13
|
*/
|
|
12
14
|
import type { CommandContext } from "../cli/registry.js";
|
|
13
15
|
import { type IntentRecordDocument } from "./intent-record.js";
|
|
16
|
+
import type { IntentTrace } from "./intent-trace.js";
|
|
14
17
|
import { type IntentDocument, type WhyAnswer } from "./intent.js";
|
|
15
18
|
type Result = Exclude<IntentDocument, {
|
|
16
19
|
error: unknown;
|
|
@@ -22,6 +25,12 @@ type RecordResult = Exclude<IntentRecordDocument, {
|
|
|
22
25
|
export declare const IN_WINDOW_QUESTION = "is this drift, a superseding decision nobody wrote down, or the decision being wrong?";
|
|
23
26
|
/** Why the region is like this (#3034): the decisions most relevant first, then who made each span of its current lines, then the gaps. */
|
|
24
27
|
export declare function whyLines(doc: Result, why: WhyAnswer): string[];
|
|
28
|
+
/**
|
|
29
|
+
* The why chain (#4023), in its order: for each commit that names a work item
|
|
30
|
+
* or was tagged, released or deployed, a line; then each release with its
|
|
31
|
+
* cuts, gates and deploys, and the deploys of no release.
|
|
32
|
+
*/
|
|
33
|
+
export declare function traceLines(trace: IntentTrace): string[];
|
|
25
34
|
/** The walk as text, one line each, in the order of #2650 section B. */
|
|
26
35
|
export declare function formatIntent(doc: Result): string;
|
|
27
36
|
/** The record walk as text: the record, its window, then each commit with its bucket, and the counts. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intent-cli.d.ts","sourceRoot":"","sources":["../../src/workspace/intent-cli.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"intent-cli.d.ts","sourceRoot":"","sources":["../../src/workspace/intent-cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAgB,KAAK,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,KAAK,EAAE,WAAW,EAAa,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAsE,KAAK,cAAc,EAAkD,KAAK,SAAS,EAAiB,MAAM,UAAU,CAAC;AAKlM,KAAK,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAC1D,KAAK,YAAY,GAAG,OAAO,CAAC,oBAAoB,EAAE;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAYtE,gIAAgI;AAChI,eAAO,MAAM,kBAAkB,0FAA0F,CAAC;AAwG1H,2IAA2I;AAC3I,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,GAAG,MAAM,EAAE,CAsB9D;AAKD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,EAAE,CA0BvD;AAED,wEAAwE;AACxE,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CA+BhD;AAED,yGAAyG;AACzG,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAwB5D;AAcD,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAuB1F"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `chant workspace graph --intent <path[:start-end]|path#symbol> [--at <rev>] [--kind <kind file>...] [--follow-squash] [--json]`
|
|
2
|
+
* `chant workspace graph --intent <path[:start-end]|path#symbol|member/node|sha> [--at <rev>] [--kind <kind file>...] [--follow-squash] [--json]`
|
|
3
3
|
* (#2651, #3034): the intent graph over one region (`intent.ts`), printed as JSON
|
|
4
4
|
* with `--json` or as a walk, one line per node, in the order of #2650
|
|
5
5
|
* section B: the region, its decisions, their artifacts, the commits, and the
|
|
@@ -7,13 +7,15 @@
|
|
|
7
7
|
* the decisions governing it, most relevant first. Under each decision come the commits made inside its window, and
|
|
8
8
|
* when any of them is not the decision's own work, the question #2650 B puts
|
|
9
9
|
* to the person about it (#2656). Without `--kind`, the walk reads every
|
|
10
|
-
* record kind the declaration names (#2680).
|
|
10
|
+
* record kind the declaration names (#2680). Last comes the why chain (#4023):
|
|
11
|
+
* each commit's work item, ci tag and release, and each release's gates and
|
|
12
|
+
* deploys.
|
|
11
13
|
*/
|
|
12
14
|
import { resolve } from "node:path";
|
|
13
15
|
import { formatError } from "../cli/format.js";
|
|
14
16
|
import { intentRecord } from "./intent-record.js";
|
|
15
17
|
import { intentGraph } from "./intent.js";
|
|
16
|
-
const USAGE = "chant workspace graph --intent <path[:start-end]|path#symbol> [--at <rev>] [--kind <kind file>...] [--follow-squash] [--json]";
|
|
18
|
+
const USAGE = "chant workspace graph --intent <path[:start-end]|path#symbol|member/node|sha> [--at <rev>] [--kind <kind file>...] [--follow-squash] [--json]";
|
|
17
19
|
const RECORD_USAGE = "chant workspace graph --intent --record <id> [--at <rev>] [--kind <kind file>...] [--follow-squash] [--json]";
|
|
18
20
|
function edgesFrom(doc, from, kind) {
|
|
19
21
|
return doc.edges.filter((e) => e.from === from && e.kind === kind);
|
|
@@ -157,6 +159,48 @@ export function whyLines(doc, why) {
|
|
|
157
159
|
out.push(` gap ${g.code}: ${g.message}${g.lines ? ` (lines ${g.lines.map(span).join(", ")})` : ""}`);
|
|
158
160
|
return out;
|
|
159
161
|
}
|
|
162
|
+
const gateLabel = (g) => `${g.op}/${g.gate}${g.environment ? ` ${g.environment}` : ""}: ${g.empty ? "passed over an empty change set" : `${g.resolvedBy}${g.relayedBy ? ` relayed by ${g.relayedBy}` : ""}`}${g.channel ? ` on ${g.channel}` : ""} at ${g.at}${g.planDigest ? `, plan ${g.planDigest.slice(0, 24)}${g.changeSet ? " (change set stored)" : ""}` : ""}${g.sealed ? ", sealed" : ""}`;
|
|
163
|
+
/**
|
|
164
|
+
* The why chain (#4023), in its order: for each commit that names a work item
|
|
165
|
+
* or was tagged, released or deployed, a line; then each release with its
|
|
166
|
+
* cuts, gates and deploys, and the deploys of no release.
|
|
167
|
+
*/
|
|
168
|
+
export function traceLines(trace) {
|
|
169
|
+
const out = [];
|
|
170
|
+
const label = (digest) => trace.releases.find((r) => r.releaseDigest === digest)?.label ?? digest.slice(0, 24);
|
|
171
|
+
for (const c of trace.commits) {
|
|
172
|
+
const parts = [];
|
|
173
|
+
if (c.work && c.work.state !== "unlinked")
|
|
174
|
+
parts.push(c.work.state === "linked" ? `work ${c.work.items.map((w) => `${w.id} (${w.source.field})`).join(", ") || "by a lease not checked"}` : `work ${c.work.state}`);
|
|
175
|
+
if (c.windowMatches.length > 0)
|
|
176
|
+
parts.push(`in the window of ${c.windowMatches.map((w) => w.id).join(", ")}`);
|
|
177
|
+
if (c.tag.state !== "none")
|
|
178
|
+
parts.push(c.tag.state);
|
|
179
|
+
for (const r of c.releases)
|
|
180
|
+
parts.push(`${r.link === "cut-from" ? "released as" : "shipped in"} ${label(r.release)}`);
|
|
181
|
+
for (const d of c.deploys)
|
|
182
|
+
parts.push(`${d.env} since ${trace.deploys.find((x) => x.id === d.deploy)?.timestamp ?? "?"}`);
|
|
183
|
+
if (parts.length > 0)
|
|
184
|
+
out.push(`trace ${short(c.sha)} ${parts.join("; ")}`);
|
|
185
|
+
}
|
|
186
|
+
for (const r of trace.releases) {
|
|
187
|
+
const cut = r.cuts[0];
|
|
188
|
+
out.push(`release ${r.label ?? r.releaseDigest.slice(0, 24)} from ${short(r.commit)}, ${r.tag.state}${cut ? `; cut by ${cut.actor} at ${cut.timestamp}${cut.signed ? ", signed" : ""}` : ""}`);
|
|
189
|
+
for (const g of r.gates)
|
|
190
|
+
out.push(` gate ${gateLabel(g)}`);
|
|
191
|
+
for (const id of r.deploys) {
|
|
192
|
+
const d = trace.deploys.find((x) => x.id === id);
|
|
193
|
+
if (d)
|
|
194
|
+
out.push(` deploy ${d.env} ${d.component} at ${d.timestamp} by ${d.actor}${d.admittedBy ? `, admitted by ${d.admittedBy.op}/${d.admittedBy.gate} (${d.admittedBy.resolvedBy})` : ""}`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
for (const d of trace.deploys.filter((x) => x.release === null)) {
|
|
198
|
+
out.push(`deploy ${d.env} ${d.component} at ${d.timestamp} by ${d.actor} from ${short(d.gitSha)}, no release${d.admittedBy ? `; admitted by ${gateLabel(d.admittedBy)}` : ""}${d.plan ? `; plan ${d.plan.document.digest.slice(0, 24)}` : ""}`);
|
|
199
|
+
}
|
|
200
|
+
for (const x of trace.reasons)
|
|
201
|
+
out.push(`reason ${x.code}: ${x.message}`);
|
|
202
|
+
return out;
|
|
203
|
+
}
|
|
160
204
|
/** The walk as text, one line each, in the order of #2650 section B. */
|
|
161
205
|
export function formatIntent(doc) {
|
|
162
206
|
const out = [];
|
|
@@ -165,7 +209,10 @@ export function formatIntent(doc) {
|
|
|
165
209
|
const lines = region.lines ? `:${region.lines.start}${region.lines.end === region.lines.start ? "" : `-${region.lines.end}`}` : "";
|
|
166
210
|
const where = doc.at ? `at ${short(doc.at)}` : "in the working tree";
|
|
167
211
|
const symbol = region.symbol ? `#${region.symbol.name} (${region.symbol.kind} ${region.symbol.qualified}, lines ${region.lines ? span(region.lines) : "none"})` : lines;
|
|
168
|
-
|
|
212
|
+
if (region.commit)
|
|
213
|
+
out.push(`region commit ${short(region.commit)} (member ${region.member ?? "none"}) ${doc.at ? `at ${short(doc.at)}` : "in the working tree"}`);
|
|
214
|
+
else
|
|
215
|
+
out.push(`region ${region.path}${symbol} (${region.type}, member ${region.member ?? "none"}${region.generated ? ", generated" : ""}) ${where}${region.node ? `, from node ${region.node}` : ""}`);
|
|
169
216
|
}
|
|
170
217
|
const files = ofKind(doc, "file");
|
|
171
218
|
if (files.length > 0)
|
|
@@ -190,6 +237,8 @@ export function formatIntent(doc) {
|
|
|
190
237
|
out.push(`reason ${r.code}: ${r.message}`);
|
|
191
238
|
if (doc.why)
|
|
192
239
|
out.push(...whyLines(doc, doc.why));
|
|
240
|
+
if (doc.trace)
|
|
241
|
+
out.push(...traceLines(doc.trace));
|
|
193
242
|
const kinds = doc.kinds.length === 0 ? "; no --kind, so no decisions were read" : "";
|
|
194
243
|
const work = ofKind(doc, "work").length;
|
|
195
244
|
out.push(`${doc.summary.commits} commits, ${doc.summary.decisions} decisions, ${work > 0 ? `${work} work ${work === 1 ? "item" : "items"}, ` : ""}${doc.summary.artifacts} artifacts, ${doc.summary.findings} findings${kinds}`);
|
|
@@ -245,7 +294,7 @@ export async function runWorkspaceIntent(ctx, cwd) {
|
|
|
245
294
|
return runRecord(ctx, cwd, args.kinds ?? (args.kind !== undefined ? [args.kind] : undefined));
|
|
246
295
|
}
|
|
247
296
|
if (!args.intent) {
|
|
248
|
-
console.error(formatError({ message: "--intent needs a region: a path, path:line, path:start-end
|
|
297
|
+
console.error(formatError({ message: "--intent needs a region: a path, path:line, path:start-end, path#symbol, a graph node id or a commit sha", hint: USAGE }));
|
|
249
298
|
return 1;
|
|
250
299
|
}
|
|
251
300
|
// No --kind: undefined, so the walk reads the kinds the declaration names (#2680).
|