@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
package/src/workspace/intent.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The intent graph over one region: `chant workspace graph --intent
|
|
3
|
-
* <path[:start-end]|path#symbol>` (#2651; #2650 sections B and C1; #2524 D8,
|
|
3
|
+
* <path[:start-end]|path#symbol|member/node|sha>` (#2651; #2650 sections B and C1; #2524 D8,
|
|
4
4
|
* D15; #3034).
|
|
5
5
|
*
|
|
6
6
|
* A person points at some code and asks how it got this way and who decided
|
|
@@ -77,6 +77,7 @@ import { followSquashes, squashLineOrigins, type Forge, type SquashFollow } from
|
|
|
77
77
|
import { memberDirOnDisk, memberSymbolResolvers, type SymbolPluginLoader } from "./lexicon-symbols";
|
|
78
78
|
import { resolveSymbol, symbolResolverFor, type SymbolResolver } from "./symbols";
|
|
79
79
|
import { readTrailerJoins, type CommitTrailerJoins } from "./trailer-joins";
|
|
80
|
+
import { buildTrace, type IntentTrace } from "./intent-trace";
|
|
80
81
|
import { joinPath, skippedDir, workingTree, type WorkspaceTree } from "./tree";
|
|
81
82
|
import { activeAttestors, type ProvenanceLevel } from "./trust/attestor";
|
|
82
83
|
import { commitProvenance, policyAtBase, resolveBase } from "./trust/provenance";
|
|
@@ -204,9 +205,12 @@ export interface RegionNode {
|
|
|
204
205
|
/** The member whose directory holds the path, or null. */
|
|
205
206
|
member: string | null;
|
|
206
207
|
at: string | null;
|
|
207
|
-
|
|
208
|
-
|
|
208
|
+
/** `commit` for a region given as a commit sha (#4023): the files that commit changed. */
|
|
209
|
+
type: "file" | "dir" | "commit";
|
|
210
|
+
/** For a file region, whether the file is generated (#2524 D14); null for a directory or a commit. */
|
|
209
211
|
generated: boolean | null;
|
|
212
|
+
/** Set when the region was given as a commit sha (#4023): its full sha. `path` is then `.`. */
|
|
213
|
+
commit?: string;
|
|
210
214
|
/** Set when the region was given as a graph node id. */
|
|
211
215
|
node: string | null;
|
|
212
216
|
/** Set when the region was given as `path#symbol` (#3034): the symbol as given, the declaration it resolved to, and its kind. `lines` holds its current lines. */
|
|
@@ -444,6 +448,16 @@ export interface WorkNode {
|
|
|
444
448
|
* to the review through it. Empty when none does. Added within contract 1.
|
|
445
449
|
*/
|
|
446
450
|
reviews?: WorkReview[];
|
|
451
|
+
/**
|
|
452
|
+
* The other in-flight work items whose linked commits touch a file this
|
|
453
|
+
* item's linked commits touch (#4025), as `workspace status --json` reports
|
|
454
|
+
* in `overlap`, each with the shared files. Empty when none does, or when
|
|
455
|
+
* this item is not in flight. Absent on a read with `--at` and when the
|
|
456
|
+
* overlap can't be read. The change-set entries two items share are in
|
|
457
|
+
* `status`, which reads the gates. Added within contract 1 by chant
|
|
458
|
+
* 0.124.29.
|
|
459
|
+
*/
|
|
460
|
+
overlaps?: { with: string; files: string[] }[];
|
|
447
461
|
}
|
|
448
462
|
|
|
449
463
|
/**
|
|
@@ -582,20 +596,22 @@ export type IntentDocument =
|
|
|
582
596
|
at: string | null;
|
|
583
597
|
workspace: { name: string; root: string };
|
|
584
598
|
region: string;
|
|
585
|
-
history: { rev: string | null; follows: "line-range" | "file" | "directory"; shallow: boolean };
|
|
599
|
+
history: { rev: string | null; follows: "line-range" | "file" | "directory" | "commit"; shallow: boolean };
|
|
586
600
|
kinds: { file: string; name: string; records: string | null; joins: "function" | "data" | null }[];
|
|
587
601
|
nodes: IntentNode[];
|
|
588
602
|
edges: IntentEdge[];
|
|
589
603
|
reasons: IntentReason[];
|
|
590
604
|
summary: { commits: number; decisions: number; artifacts: number; findings: number };
|
|
591
605
|
why: WhyAnswer;
|
|
606
|
+
/** The why chain (#4023): each commit's work item, ci tag, release, gate resolutions and deploys. Added within contract 1 by chant 0.124.29. */
|
|
607
|
+
trace?: IntentTrace;
|
|
592
608
|
})
|
|
593
609
|
| (Head & { error: { code: IntentErrorCode; message: string } });
|
|
594
610
|
|
|
595
611
|
export interface IntentQuery {
|
|
596
612
|
/** Where the walk up to the declaration starts, and what the region path is relative to. */
|
|
597
613
|
cwd: string;
|
|
598
|
-
/** `path`, `path:line`, `path:start-end` or `path#symbol`,
|
|
614
|
+
/** `path`, `path:line`, `path:start-end` or `path#symbol`, a graph node id `<member>/<id>`, or a commit sha (#4023). */
|
|
599
615
|
region: string;
|
|
600
616
|
at?: string;
|
|
601
617
|
/** Follow squash merges to their pull requests' original commits, fetching a missing pull request ref from `origin` (#3035). */
|
|
@@ -767,6 +783,22 @@ export function closingCommit(top: string, rev: string, path: string, stateField
|
|
|
767
783
|
return closing;
|
|
768
784
|
}
|
|
769
785
|
|
|
786
|
+
/**
|
|
787
|
+
* The files a commit changed, from the workspace root (#4023): against its
|
|
788
|
+
* first parent, or every file for a root commit. Files outside the workspace
|
|
789
|
+
* are left out.
|
|
790
|
+
*/
|
|
791
|
+
export function changedFiles(top: string, sha: string, workspacePrefix: string): string[] {
|
|
792
|
+
const out = tryGit(top, ["diff-tree", "--no-commit-id", "-r", "--name-only", "--root", "-m", "--first-parent", "-z", sha]) ?? "";
|
|
793
|
+
const files = new Set<string>();
|
|
794
|
+
for (const f of out.split("\0")) {
|
|
795
|
+
if (!f) continue;
|
|
796
|
+
if (workspacePrefix === "") files.add(f);
|
|
797
|
+
else if (f.startsWith(`${workspacePrefix}/`)) files.add(f.slice(workspacePrefix.length + 1));
|
|
798
|
+
}
|
|
799
|
+
return [...files].sort();
|
|
800
|
+
}
|
|
801
|
+
|
|
770
802
|
/** The commit a decision record's window opens at: the one that decided it, or, when it is not approved, the one that added it. */
|
|
771
803
|
export function windowOpening(top: string, rev: string, view: Pick<RecordView, "path" | "decidedIn">): string | null {
|
|
772
804
|
return view.decidedIn?.sha ?? addingCommit(top, rev, view.path);
|
|
@@ -973,8 +1005,13 @@ interface ResolvedRegion {
|
|
|
973
1005
|
lines: LineRange | null;
|
|
974
1006
|
node: string | null;
|
|
975
1007
|
symbol: { name: string; qualified: string; kind: string } | null;
|
|
1008
|
+
/** The full sha, for a region given as a commit (#4023). */
|
|
1009
|
+
commit?: string;
|
|
976
1010
|
}
|
|
977
1011
|
|
|
1012
|
+
/** A commit sha as a region may give it: 7 to 64 hex digits. */
|
|
1013
|
+
const COMMIT_REGION = /^[0-9a-fA-F]{7,64}$/;
|
|
1014
|
+
|
|
978
1015
|
async function resolveRegion(query: IntentQuery, located: LocatedWorkspace, declaration: Declaration): Promise<ResolvedRegion> {
|
|
979
1016
|
const parsed = parseRegion(query.region);
|
|
980
1017
|
if ("error" in parsed) throw new IntentError("intent-region-invalid", parsed.error);
|
|
@@ -1019,10 +1056,38 @@ async function resolveRegion(query: IntentQuery, located: LocatedWorkspace, decl
|
|
|
1019
1056
|
return { path: file === "" ? "." : file, lines: loc.line ? { start: loc.line, end: loc.line } : null, node: query.region, symbol: null };
|
|
1020
1057
|
}
|
|
1021
1058
|
}
|
|
1022
|
-
|
|
1059
|
+
// A commit sha, when no path or node has the name (#4023): the commit and the files it changed.
|
|
1060
|
+
if (COMMIT_REGION.test(query.region) && located.top) {
|
|
1061
|
+
const sha = tryGit(located.top, ["rev-parse", "--verify", "--quiet", `${query.region}^{commit}`])?.trim();
|
|
1062
|
+
if (sha) return { path: ".", lines: null, node: null, symbol: null, commit: sha };
|
|
1063
|
+
}
|
|
1064
|
+
throw new IntentError("intent-region-invalid", `${query.region} is not a path in the workspace${located.tree.label}, a path#symbol, a graph node id or a commit`);
|
|
1023
1065
|
}
|
|
1024
1066
|
|
|
1025
1067
|
/** Build the intent document. Never throws an {@link IntentError}, {@link WorkspaceReadError} or {@link RecordReadError}. */
|
|
1068
|
+
/**
|
|
1069
|
+
* Give each work node the in-flight items it overlaps by file (#4025). Only a
|
|
1070
|
+
* working-tree read, since the overlap is about the branches as they are now;
|
|
1071
|
+
* a read that fails leaves the field off.
|
|
1072
|
+
*/
|
|
1073
|
+
async function addOverlaps(work: WorkNode[], declaration: Declaration, root: string, top: string, at: string | null): Promise<void> {
|
|
1074
|
+
if (work.length === 0 || at !== null) return;
|
|
1075
|
+
let report: import("./overlap").OverlapReport | null;
|
|
1076
|
+
try {
|
|
1077
|
+
const { readOverlap } = await import("./overlap");
|
|
1078
|
+
report = await readOverlap({ declaration, root, top, changeSets: [] });
|
|
1079
|
+
} catch {
|
|
1080
|
+
return;
|
|
1081
|
+
}
|
|
1082
|
+
if (report === null) return;
|
|
1083
|
+
for (const n of work) {
|
|
1084
|
+
const self = `${n.recordKind}:${n.record}`;
|
|
1085
|
+
n.overlaps = report.pairs
|
|
1086
|
+
.filter((p) => p.items.includes(self) && p.files.length > 0)
|
|
1087
|
+
.map((p) => ({ with: p.items[0] === self ? p.items[1] : p.items[0], files: p.files }));
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1026
1091
|
export async function intentGraph(query: IntentQuery): Promise<IntentResult> {
|
|
1027
1092
|
const head: Head = { $schema: INTENT_OUTPUT_SCHEMA_ID, contract: INTENT_CONTRACT_VERSION, chant: readerVersion() };
|
|
1028
1093
|
try {
|
|
@@ -1041,7 +1106,7 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
1041
1106
|
if (!top) throw new IntentError("not-a-git-repository", "the intent graph reads git history, and this directory is not in a git repository");
|
|
1042
1107
|
const declaration = readDeclaration(located.tree, "", { rootChant: true });
|
|
1043
1108
|
const region = await resolveRegion(query, located, declaration);
|
|
1044
|
-
const type = region.path === "." ? "dir" : located.tree.stat(region.path);
|
|
1109
|
+
const type: "file" | "dir" | "commit" | undefined = region.commit ? "commit" : region.path === "." ? "dir" : located.tree.stat(region.path);
|
|
1045
1110
|
if (!type) throw new IntentError("intent-region-invalid", `${region.path} does not exist${located.tree.label}`);
|
|
1046
1111
|
if (region.lines) {
|
|
1047
1112
|
if (type !== "file") throw new IntentError("intent-region-invalid", `${region.path} is a directory, and a line range needs a file`);
|
|
@@ -1065,8 +1130,21 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
1065
1130
|
};
|
|
1066
1131
|
|
|
1067
1132
|
// The region, its files and its member.
|
|
1068
|
-
|
|
1069
|
-
const
|
|
1133
|
+
// A commit region (#4023) covers the files the commit changed, from the workspace root, and the members holding them.
|
|
1134
|
+
const workspacePrefix = located.root === "." ? "" : located.root;
|
|
1135
|
+
const changed = region.commit ? changedFiles(top, region.commit, workspacePrefix) : [];
|
|
1136
|
+
const changedMembers = [...new Set(changed.map((f) => memberHolding(f, declaration.members)).filter((m): m is string => m !== null))];
|
|
1137
|
+
const member = region.commit
|
|
1138
|
+
? changedMembers.length === 1
|
|
1139
|
+
? changedMembers[0]
|
|
1140
|
+
: null
|
|
1141
|
+
: region.path === "."
|
|
1142
|
+
? (declaration.members.find((m) => m.dir === ".")?.name ?? null)
|
|
1143
|
+
: memberHolding(region.path, declaration.members);
|
|
1144
|
+
const regionMembers = region.commit ? changedMembers : member ? [member] : [];
|
|
1145
|
+
const rid = region.commit ? `region:commit:${region.commit}` : regionId(region.path, region.lines, region.symbol?.name);
|
|
1146
|
+
/** How messages name the region: its path, or the commit. */
|
|
1147
|
+
const regionLabel = region.commit ? `commit ${region.commit.slice(0, 8)}` : region.path;
|
|
1070
1148
|
add<RegionNode>({
|
|
1071
1149
|
id: rid,
|
|
1072
1150
|
kind: "region",
|
|
@@ -1078,6 +1156,7 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
1078
1156
|
generated: type === "file" ? isGeneratedPath(declaration, region.path) : null,
|
|
1079
1157
|
node: region.node,
|
|
1080
1158
|
symbol: region.symbol,
|
|
1159
|
+
...(region.commit ? { commit: region.commit } : {}),
|
|
1081
1160
|
});
|
|
1082
1161
|
const files = type === "dir" ? filesUnder(located.tree, region.path) : [];
|
|
1083
1162
|
for (const f of files) add<FileNode>({ id: `file:${f}`, kind: "file", path: f, member: memberHolding(f, declaration.members), generated: isGeneratedPath(declaration, f) });
|
|
@@ -1091,9 +1170,8 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
1091
1170
|
const rev = located.at ?? (tryGit(top, ["rev-parse", "--verify", "--quiet", "HEAD^{commit}"])?.trim() || null);
|
|
1092
1171
|
const shallow = tryGit(top, ["rev-parse", "--is-shallow-repository"])?.trim() === "true";
|
|
1093
1172
|
if (shallow) reasons.push({ code: "intent-history-shallow", message: "this is a shallow clone, so the history stops at its boundary and the oldest commit listed may stand for many" });
|
|
1094
|
-
const workspacePrefix = located.root === "." ? "" : located.root;
|
|
1095
1173
|
const gitPath = joinPath(workspacePrefix, region.path);
|
|
1096
|
-
const touched = rev ? regionHistory(top, rev, gitPath, type, region.lines) : [];
|
|
1174
|
+
const touched = region.commit ? [{ sha: region.commit, lines: null }] : rev && type !== "commit" ? regionHistory(top, rev, gitPath, type, region.lines) : [];
|
|
1097
1175
|
// Who last wrote each current line of a file region (#3034). A commit blame
|
|
1098
1176
|
// names and the history walk missed, as when a move confuses git log -L,
|
|
1099
1177
|
// joins the commits that touched the region.
|
|
@@ -1309,14 +1387,16 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
1309
1387
|
const p = entry.slice("path:".length);
|
|
1310
1388
|
if (!isWorkspacePath(p)) continue;
|
|
1311
1389
|
const full = joinPath(kindPrefix, p);
|
|
1312
|
-
if (
|
|
1390
|
+
if (type === "commit") {
|
|
1391
|
+
if (changed.some((f) => constraintCovers(full, joinPath(workspacePrefix, f)))) matched.push({ entry, granularity: "path", to: rid });
|
|
1392
|
+
} else if (regionFull !== "" && constraintCovers(full, regionFull)) {
|
|
1313
1393
|
matched.push({ entry, granularity: "path", to: rid });
|
|
1314
1394
|
} else if (type === "dir" && full !== regionFull && (regionFull === "" || full.startsWith(`${regionFull}/`))) {
|
|
1315
1395
|
// A path below a directory region constrains the files under it, not the whole region.
|
|
1316
1396
|
for (const f of fileNodesUnder(full)) matched.push({ entry, granularity: "path", to: `file:${f}` });
|
|
1317
1397
|
}
|
|
1318
1398
|
} else if (entry.startsWith("member:")) {
|
|
1319
|
-
if (
|
|
1399
|
+
if (regionMembers.includes(entry.slice("member:".length))) matched.push({ entry, granularity: "member", to: rid });
|
|
1320
1400
|
} else {
|
|
1321
1401
|
const issue = entry.match(ISSUE);
|
|
1322
1402
|
if (issue && origin !== null && issue[1].toLowerCase() === origin && commitRefs.has(issue[2])) matched.push({ entry, granularity: "issue", to: rid });
|
|
@@ -1691,7 +1771,7 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
1691
1771
|
if (h.node!.constrains.some((x) => x.granularity === "path") && inWorkWindow(h, t.sha)) edges.push({ kind: "within", from: c.id, to: h.node!.id, state: "worked" });
|
|
1692
1772
|
}
|
|
1693
1773
|
if (readsRecords && c.state === "undecided") {
|
|
1694
|
-
find("intent-commit-undecided", `${t.sha.slice(0, 8)} changed the region when no decision constrained ${
|
|
1774
|
+
find("intent-commit-undecided", `${t.sha.slice(0, 8)} changed the region when no decision constrained ${regionLabel} by path`, [c.id, rid]);
|
|
1695
1775
|
}
|
|
1696
1776
|
if (readsRecords && !j.unit && j.carries.length === 0 && c.pullRequest === null && coveredAt(t.sha, ["path", "member", "contract", "issue"]).length === 0) {
|
|
1697
1777
|
find("intent-commit-bare", `${t.sha.slice(0, 8)} names no unit, no record, no pull request and no decision`, [c.id]);
|
|
@@ -1706,11 +1786,11 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
1706
1786
|
if (readsRecords) {
|
|
1707
1787
|
const current = covering.filter((c) => c.node.supersededBy === null);
|
|
1708
1788
|
if (covering.length === 0) {
|
|
1709
|
-
find("intent-region-unconstrained", `no decision constrains ${
|
|
1789
|
+
find("intent-region-unconstrained", `no decision constrains ${regionLabel}`, [rid]);
|
|
1710
1790
|
} else if (current.length === 0) {
|
|
1711
|
-
find("intent-decision-superseded-live", `every decision constraining ${
|
|
1791
|
+
find("intent-decision-superseded-live", `every decision constraining ${regionLabel} is superseded: ${covering.map((c) => `${c.node.record} by ${c.node.supersededBy}`).join(", ")}`, [rid, ...covering.map((c) => c.node.id)]);
|
|
1712
1792
|
} else if (current.every((c) => !c.node.closed)) {
|
|
1713
|
-
find("intent-decision-provisional", `the decisions constraining ${
|
|
1793
|
+
find("intent-decision-provisional", `the decisions constraining ${regionLabel} are ${[...new Set(current.map((c) => c.node.state ?? "stateless"))].join(" or ")}, and none is in a closed state`, [rid, ...current.map((c) => c.node.id)]);
|
|
1714
1794
|
}
|
|
1715
1795
|
// A current decision with a dissent nobody addressed or withdrew (#2686), from its quorum.
|
|
1716
1796
|
for (const c of current) {
|
|
@@ -1721,14 +1801,14 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
1721
1801
|
id: `finding:intent-decision-contested:${findings.filter((f) => f.code === "intent-decision-contested").length + 1}`,
|
|
1722
1802
|
kind: "finding",
|
|
1723
1803
|
code: "intent-decision-contested",
|
|
1724
|
-
message: `${c.node.record} constrains ${
|
|
1804
|
+
message: `${c.node.record} constrains ${regionLabel} and has ${open.length} open ${open.length === 1 ? "concern" : "concerns"}, from ${open.map((o) => o.reviewer).join(", ")}: a dissent neither addressed nor withdrawn`,
|
|
1725
1805
|
concerns: [c.node.id, rid],
|
|
1726
1806
|
openConcerns: { count: open.length, principals },
|
|
1727
1807
|
});
|
|
1728
1808
|
}
|
|
1729
1809
|
const granularities = new Set(covering.flatMap((c) => c.node.constrains.map((x) => x.granularity)));
|
|
1730
1810
|
if (covering.length > 0 && !granularities.has("path") && granularities.has("member")) {
|
|
1731
|
-
find("intent-constraint-coarse", `${
|
|
1811
|
+
find("intent-constraint-coarse", `${regionLabel} is constrained only through its member, ${regionMembers.join(", ")}`, [rid, ...covering.map((c) => c.node.id)]);
|
|
1732
1812
|
}
|
|
1733
1813
|
}
|
|
1734
1814
|
|
|
@@ -1739,7 +1819,7 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
1739
1819
|
if (implementersOf(c.node).length > 0) continue;
|
|
1740
1820
|
const w = windows.get(c.node.id);
|
|
1741
1821
|
if (w && touched.some((t) => w.from.has(t.sha) && !w.until?.has(t.sha))) continue;
|
|
1742
|
-
find("intent-decision-unimplemented", `${c.node.record} is ${c.node.state} and constrains ${
|
|
1822
|
+
find("intent-decision-unimplemented", `${c.node.record} is ${c.node.state} and constrains ${regionLabel}, and no work item that is not dropped implements it, and no commit changed the region in its window`, [c.node.id, rid]);
|
|
1743
1823
|
}
|
|
1744
1824
|
for (const h of workCovering) {
|
|
1745
1825
|
const node = h.node!;
|
|
@@ -1757,7 +1837,7 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
1757
1837
|
if (impl.length === 0 || impl.some((h) => h.view.state === workSpec(h).done)) continue;
|
|
1758
1838
|
find(
|
|
1759
1839
|
"intent-work-open-decided-code",
|
|
1760
|
-
`${own.length} ${own.length === 1 ? "commit" : "commits"} in ${
|
|
1840
|
+
`${own.length} ${own.length === 1 ? "commit" : "commits"} in ${regionLabel} ${own.length === 1 ? "is" : "are"} ${d.record}'s own work, and ${impl.map((h) => `${h.view.id} is ${h.view.state ?? "stateless"}`).join(", ")}: the code says done and the queue says not`,
|
|
1761
1841
|
[d.id, ...own, ...impl.map((h) => workNode(h).id)],
|
|
1762
1842
|
);
|
|
1763
1843
|
}
|
|
@@ -1827,6 +1907,7 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
1827
1907
|
const kindPrefix = h.kind.records!.workspaceRoot === "." ? "" : h.kind.records!.workspaceRoot;
|
|
1828
1908
|
const full = joinPath(kindPrefix, parsed.path);
|
|
1829
1909
|
const contains = (a: string, b: string) => a === b || a === "" || b.startsWith(`${a}/`);
|
|
1910
|
+
if (type === "commit") return changed.some((f) => contains(full, joinPath(workspacePrefix, f)) || contains(joinPath(workspacePrefix, f), full));
|
|
1830
1911
|
if (!contains(full, regionFull) && !contains(regionFull, full)) return false;
|
|
1831
1912
|
if (full === regionFull && parsed.lines && region.lines) return parsed.lines.start <= region.lines.end && region.lines.start <= parsed.lines.end;
|
|
1832
1913
|
return true;
|
|
@@ -1840,7 +1921,7 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
1840
1921
|
if (gap && h.view.state === workSpec(h).done) {
|
|
1841
1922
|
const node = workNode(h);
|
|
1842
1923
|
if (!node.warnings.some((w) => w.code === "work-done-gap-open")) {
|
|
1843
|
-
node.warnings.push({ code: "work-done-gap-open", message: `${node.record} is ${h.view.state}, and ${f.code}, the gap it came from, still fires on ${
|
|
1924
|
+
node.warnings.push({ code: "work-done-gap-open", message: `${node.record} is ${h.view.state}, and ${f.code}, the gap it came from, still fires on ${regionLabel}` });
|
|
1844
1925
|
}
|
|
1845
1926
|
}
|
|
1846
1927
|
}
|
|
@@ -1879,15 +1960,56 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
1879
1960
|
}
|
|
1880
1961
|
}
|
|
1881
1962
|
for (const f of findings) nodes.set(f.id, f);
|
|
1963
|
+
await addOverlaps([...nodes.values()].filter((n): n is WorkNode => n.kind === "work"), declaration, located.rootOnDisk, top, located.at);
|
|
1882
1964
|
const why = explain();
|
|
1883
1965
|
const all = [...nodes.values()];
|
|
1966
|
+
|
|
1967
|
+
// The why chain (#4023): each commit's work item, ci tag, release, gate resolutions and deploys.
|
|
1968
|
+
const workIds = new Map<string, Set<string>>();
|
|
1969
|
+
const workNodeIds = new Map<string, string>();
|
|
1970
|
+
for (const h of workAll) {
|
|
1971
|
+
const name = h.kind.records!.loaded.kind.name;
|
|
1972
|
+
(workIds.get(name) ?? workIds.set(name, new Set()).get(name)!).add(h.view.id!);
|
|
1973
|
+
if (h.node) workNodeIds.set(`${name}:${h.view.id}`, h.node.id);
|
|
1974
|
+
}
|
|
1975
|
+
for (const k of workKinds) if (!workIds.has(k.records!.loaded.kind.name)) workIds.set(k.records!.loaded.kind.name, new Set());
|
|
1976
|
+
const windowsOf = new Map<string, { id: string; node: string; path: string }[]>();
|
|
1977
|
+
for (const e of edges) {
|
|
1978
|
+
if (e.kind !== "within" || e.state !== "worked") continue;
|
|
1979
|
+
const w = nodes.get(e.to) as WorkNode | undefined;
|
|
1980
|
+
if (!w) continue;
|
|
1981
|
+
const sha = e.from.slice("commit:".length);
|
|
1982
|
+
(windowsOf.get(sha) ?? windowsOf.set(sha, []).get(sha)!).push({ id: `${w.recordKind}:${w.record}`, node: w.id, path: w.path });
|
|
1983
|
+
}
|
|
1984
|
+
const later = new Map<string, Set<string>>();
|
|
1985
|
+
const trace = await buildTrace({
|
|
1986
|
+
top,
|
|
1987
|
+
commits: all.filter((n): n is CommitNode => n.kind === "commit").map((c) => ({ id: c.id, sha: c.sha, trailers: c.trailers, joins: c.joins })),
|
|
1988
|
+
work: readsWork ? { index: { kinds: workIds }, nodes: workNodeIds } : null,
|
|
1989
|
+
windows: windowsOf,
|
|
1990
|
+
// The region's member's ledger; for a region in no member, every member's and the workspace's own.
|
|
1991
|
+
ledgers: (regionMembers.length > 0 ? regionMembers : declaration.members.map((m) => m.name))
|
|
1992
|
+
.map((name) => {
|
|
1993
|
+
const dir = declaration.members.find((m) => m.name === name)!.dir;
|
|
1994
|
+
return { member: name as string | null, cwd: memberDirOnDisk(located.rootOnDisk, dir), within: dir === "." ? null : `_members/${name}/` };
|
|
1995
|
+
})
|
|
1996
|
+
.concat(regionMembers.length > 0 ? [] : [{ member: null, cwd: located.rootOnDisk, within: null }]),
|
|
1997
|
+
green: declaration.ci?.green ?? null,
|
|
1998
|
+
contains: (sha, commit) => {
|
|
1999
|
+
if (commit === sha) return true;
|
|
2000
|
+
if (!rev || !FULL_COMMIT_ID.test(commit)) return false;
|
|
2001
|
+
let set = later.get(sha);
|
|
2002
|
+
if (!set) later.set(sha, (set = descendants(top, sha, rev)));
|
|
2003
|
+
return set.has(commit);
|
|
2004
|
+
},
|
|
2005
|
+
});
|
|
1884
2006
|
return {
|
|
1885
2007
|
doc: {
|
|
1886
2008
|
...head,
|
|
1887
2009
|
at: located.at,
|
|
1888
2010
|
workspace: { name: declaration.name, root: located.root },
|
|
1889
2011
|
region: rid,
|
|
1890
|
-
history: { rev, follows: region.lines ? "line-range" : type === "file" ? "file" : "directory", shallow },
|
|
2012
|
+
history: { rev, follows: region.commit ? "commit" : region.lines ? "line-range" : type === "file" ? "file" : "directory", shallow },
|
|
1891
2013
|
kinds: kinds.map((k) => ({ file: k.display, name: k.name, records: k.records?.loaded.kind.name ?? null, joins: k.joins?.form ?? null })),
|
|
1892
2014
|
nodes: all,
|
|
1893
2015
|
edges,
|
|
@@ -1899,6 +2021,7 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
1899
2021
|
findings: findings.length,
|
|
1900
2022
|
},
|
|
1901
2023
|
why,
|
|
2024
|
+
trace,
|
|
1902
2025
|
},
|
|
1903
2026
|
failed: reasons.some((r) => r.code === "intent-plugin-failed"),
|
|
1904
2027
|
};
|
|
@@ -2019,12 +2142,12 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
2019
2142
|
if (!explained) {
|
|
2020
2143
|
gaps.push({
|
|
2021
2144
|
code: "intent-why-no-decision",
|
|
2022
|
-
message: readsRecords ? `no current decision governs ${
|
|
2145
|
+
message: readsRecords ? `no current decision governs ${regionLabel}, and none is carried out by what made its lines` : `no record kind was read, so no decision can account for ${regionLabel}`,
|
|
2023
2146
|
});
|
|
2024
2147
|
}
|
|
2025
2148
|
const committed = who.filter((w) => w.sha !== null);
|
|
2026
2149
|
if (fileLines !== null ? committed.length > 0 && committed.every((w) => w.runs.length === 0) : touched.length > 0 && runNodes.length === 0) {
|
|
2027
|
-
gaps.push({ code: "intent-why-no-run", message: `no agent run is joined to the commits that made ${fileLines !== null ? "the current lines of " : ""}${
|
|
2150
|
+
gaps.push({ code: "intent-why-no-run", message: `no agent run is joined to the commits that made ${fileLines !== null ? "the current lines of " : ""}${regionLabel}` });
|
|
2028
2151
|
}
|
|
2029
2152
|
const uncommitted = who.filter((w) => w.sha === null).map((w) => w.line);
|
|
2030
2153
|
if (uncommitted.length > 0) gaps.push({ code: "intent-why-uncommitted", message: `${uncommitted.length} ${uncommitted.length === 1 ? "line is" : "lines are"} not committed yet`, lines: ranges(uncommitted) });
|