@intentius/chant 0.102.0 → 0.104.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/audit/core.d.ts +2 -0
- package/dist/audit/core.d.ts.map +1 -1
- package/dist/audit/discover.d.ts.map +1 -1
- package/dist/change-set.d.ts +232 -0
- package/dist/change-set.d.ts.map +1 -0
- package/dist/cli/commands/audit.d.ts +7 -0
- package/dist/cli/commands/audit.d.ts.map +1 -1
- package/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/change-set.d.ts +11 -0
- package/dist/cli/handlers/change-set.d.ts.map +1 -0
- package/dist/cli/handlers/fan-out.d.ts +33 -0
- package/dist/cli/handlers/fan-out.d.ts.map +1 -1
- package/dist/cli/handlers/operator.d.ts +7 -0
- package/dist/cli/handlers/operator.d.ts.map +1 -1
- package/dist/cli/handlers/pr.d.ts +31 -0
- package/dist/cli/handlers/pr.d.ts.map +1 -0
- package/dist/cli/handlers/run.d.ts.map +1 -1
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/mcp/op-tools.d.ts.map +1 -1
- package/dist/cli/mcp/workspace-tools.d.ts +3 -2
- package/dist/cli/mcp/workspace-tools.d.ts.map +1 -1
- package/dist/cli/registry.d.ts +63 -1
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/components/auto-release.d.ts +16 -0
- package/dist/components/auto-release.d.ts.map +1 -1
- package/dist/components/capability.d.ts +53 -0
- package/dist/components/capability.d.ts.map +1 -1
- package/dist/components/changed-files.d.ts +31 -0
- package/dist/components/changed-files.d.ts.map +1 -0
- package/dist/components/cli-support.d.ts +9 -1
- package/dist/components/cli-support.d.ts.map +1 -1
- package/dist/components/component.d.ts +24 -0
- package/dist/components/component.d.ts.map +1 -1
- package/dist/components/deploy-units.d.ts.map +1 -1
- package/dist/components/driver.d.ts +13 -0
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/fan-out-output.d.ts +6 -0
- package/dist/components/fan-out-output.d.ts.map +1 -1
- package/dist/components/fan-out-record.d.ts +41 -0
- package/dist/components/fan-out-record.d.ts.map +1 -0
- package/dist/components/fan-out-run.d.ts +65 -0
- package/dist/components/fan-out-run.d.ts.map +1 -1
- package/dist/components/fan-out-support.d.ts +2 -0
- package/dist/components/fan-out-support.d.ts.map +1 -1
- package/dist/components/fan-out.d.ts +6 -0
- package/dist/components/fan-out.d.ts.map +1 -1
- package/dist/components/gated-wave-pipeline.d.ts +50 -0
- package/dist/components/gated-wave-pipeline.d.ts.map +1 -0
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/layers.d.ts +25 -0
- package/dist/components/layers.d.ts.map +1 -0
- package/dist/components/pr-pipeline.d.ts +61 -0
- package/dist/components/pr-pipeline.d.ts.map +1 -0
- package/dist/components/pr-run.d.ts +119 -0
- package/dist/components/pr-run.d.ts.map +1 -0
- package/dist/components/promote.d.ts.map +1 -1
- package/dist/components/verbs/shell.d.ts.map +1 -1
- package/dist/components/wave-plan.d.ts +49 -0
- package/dist/components/wave-plan.d.ts.map +1 -0
- package/dist/gated-waves.d.ts +147 -0
- package/dist/gated-waves.d.ts.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/lexicon.d.ts +48 -0
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/lifecycle/gate-ledger.d.ts +7 -0
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
- package/dist/lifecycle/git.d.ts +46 -1
- package/dist/lifecycle/git.d.ts.map +1 -1
- package/dist/lint/post-synth.d.ts +18 -0
- package/dist/lint/post-synth.d.ts.map +1 -1
- package/dist/op/activities/activity-contracts.d.ts +126 -0
- package/dist/op/activities/activity-contracts.d.ts.map +1 -1
- package/dist/op/activities/change-set.d.ts +62 -0
- package/dist/op/activities/change-set.d.ts.map +1 -0
- package/dist/op/activities/decide.d.ts +2 -0
- package/dist/op/activities/decide.d.ts.map +1 -1
- package/dist/op/activities/factory.d.ts +137 -0
- package/dist/op/activities/factory.d.ts.map +1 -0
- package/dist/op/activities/index.d.ts +4 -0
- package/dist/op/activities/index.d.ts.map +1 -1
- package/dist/op/activity-contract.d.ts.map +1 -1
- package/dist/op/builders.d.ts +11 -0
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/decide-backend.d.ts +5 -1
- package/dist/op/decide-backend.d.ts.map +1 -1
- package/dist/op/decide-read-inputs.d.ts +4 -2
- package/dist/op/decide-read-inputs.d.ts.map +1 -1
- package/dist/op/factory.d.ts +83 -0
- package/dist/op/factory.d.ts.map +1 -0
- package/dist/op/index.d.ts +4 -1
- package/dist/op/index.d.ts.map +1 -1
- package/dist/op/op-ir.d.ts +2 -0
- package/dist/op/op-ir.d.ts.map +1 -1
- package/dist/op/op-verb-class.d.ts.map +1 -1
- package/dist/op/types.d.ts +8 -0
- package/dist/op/types.d.ts.map +1 -1
- package/dist/op/work-lease-run.d.ts.map +1 -1
- package/dist/plan-summary.d.ts +207 -0
- package/dist/plan-summary.d.ts.map +1 -0
- package/dist/pr-forge.d.ts +105 -0
- package/dist/pr-forge.d.ts.map +1 -0
- package/dist/pr-loop.d.ts +178 -0
- package/dist/pr-loop.d.ts.map +1 -0
- package/dist/telemetry-attribution.d.ts +31 -0
- package/dist/telemetry-attribution.d.ts.map +1 -1
- package/dist/terraform/hcl2json.d.ts +45 -0
- package/dist/terraform/hcl2json.d.ts.map +1 -0
- package/dist/terraform/parse.d.ts +4 -40
- package/dist/terraform/parse.d.ts.map +1 -1
- package/dist/vendor/js-yaml-load.d.ts +56 -0
- package/dist/vendor/js-yaml-load.d.ts.map +1 -0
- package/dist/workspace/box-cli.d.ts +12 -0
- package/dist/workspace/box-cli.d.ts.map +1 -0
- package/dist/workspace/box-factory.d.ts +27 -3
- package/dist/workspace/box-factory.d.ts.map +1 -1
- package/dist/workspace/box-listing.d.ts +85 -0
- package/dist/workspace/box-listing.d.ts.map +1 -0
- package/dist/workspace/box-publish.d.ts +147 -0
- package/dist/workspace/box-publish.d.ts.map +1 -0
- package/dist/workspace/broker-protocol.d.ts +190 -0
- package/dist/workspace/broker-protocol.d.ts.map +1 -0
- package/dist/workspace/checks.d.ts.map +1 -1
- package/dist/workspace/composites.d.ts +2 -2
- package/dist/workspace/composites.d.ts.map +1 -1
- package/dist/workspace/conformance/__fixtures__/reference-broker.d.ts +17 -0
- package/dist/workspace/conformance/__fixtures__/reference-broker.d.ts.map +1 -0
- package/dist/workspace/conformance/broker.d.ts +202 -0
- package/dist/workspace/conformance/broker.d.ts.map +1 -0
- package/dist/workspace/conformance/index.d.ts +2 -1
- package/dist/workspace/conformance/index.d.ts.map +1 -1
- package/dist/workspace/conformance/vitest.d.ts +9 -2
- package/dist/workspace/conformance/vitest.d.ts.map +1 -1
- package/dist/workspace/conformance/writer.d.ts +108 -14
- package/dist/workspace/conformance/writer.d.ts.map +1 -1
- package/dist/workspace/decide.d.ts +126 -12
- package/dist/workspace/decide.d.ts.map +1 -1
- package/dist/workspace/decision-points.schema.json +11 -4
- package/dist/workspace/declaration.d.ts +65 -0
- package/dist/workspace/declaration.d.ts.map +1 -1
- package/dist/workspace/declaration.schema.json +153 -4
- package/dist/workspace/environments.d.ts +36 -10
- package/dist/workspace/environments.d.ts.map +1 -1
- package/dist/workspace/factory-rules.d.ts +180 -0
- package/dist/workspace/factory-rules.d.ts.map +1 -0
- package/dist/workspace/init.d.ts +21 -0
- package/dist/workspace/init.d.ts.map +1 -1
- package/dist/workspace/intent-cli.d.ts +1 -1
- package/dist/workspace/intent-cli.d.ts.map +1 -1
- package/dist/workspace/intent-record.d.ts +28 -1
- package/dist/workspace/intent-record.d.ts.map +1 -1
- package/dist/workspace/intent.d.ts +102 -5
- package/dist/workspace/intent.d.ts.map +1 -1
- package/dist/workspace/json-edit.d.ts +24 -0
- package/dist/workspace/json-edit.d.ts.map +1 -0
- package/dist/workspace/jsonc.d.ts +11 -0
- package/dist/workspace/jsonc.d.ts.map +1 -1
- package/dist/workspace/kinds.d.ts +48 -0
- package/dist/workspace/kinds.d.ts.map +1 -1
- package/dist/workspace/lexicon-symbols.d.ts +29 -0
- package/dist/workspace/lexicon-symbols.d.ts.map +1 -0
- package/dist/workspace/lineage-upgrade.d.ts +31 -2
- package/dist/workspace/lineage-upgrade.d.ts.map +1 -1
- package/dist/workspace/point-answer.schema.json +42 -2
- package/dist/workspace/points-cli.d.ts +10 -3
- package/dist/workspace/points-cli.d.ts.map +1 -1
- package/dist/workspace/points.d.ts +66 -5
- package/dist/workspace/points.d.ts.map +1 -1
- package/dist/workspace/reason-codes.d.ts +33 -4
- package/dist/workspace/reason-codes.d.ts.map +1 -1
- package/dist/workspace/record-sessions.d.ts +5 -7
- package/dist/workspace/record-sessions.d.ts.map +1 -1
- package/dist/workspace/records-cli.d.ts +7 -0
- package/dist/workspace/records-cli.d.ts.map +1 -1
- package/dist/workspace/records-close.d.ts +7 -3
- package/dist/workspace/records-close.d.ts.map +1 -1
- package/dist/workspace/records-write.d.ts +66 -6
- package/dist/workspace/records-write.d.ts.map +1 -1
- package/dist/workspace/records.d.ts +28 -9
- package/dist/workspace/records.d.ts.map +1 -1
- package/dist/workspace/runs-cli.d.ts +138 -6
- package/dist/workspace/runs-cli.d.ts.map +1 -1
- package/dist/workspace/runs.d.ts +132 -11
- package/dist/workspace/runs.d.ts.map +1 -1
- package/dist/workspace/session-kinds.d.ts +1 -1
- package/dist/workspace/session-kinds.d.ts.map +1 -1
- package/dist/workspace/squash.d.ts +80 -0
- package/dist/workspace/squash.d.ts.map +1 -0
- package/dist/workspace/status-gates.d.ts +2 -0
- package/dist/workspace/status-gates.d.ts.map +1 -1
- package/dist/workspace/status.d.ts +54 -0
- package/dist/workspace/status.d.ts.map +1 -1
- package/dist/workspace/symbols.d.ts +16 -5
- package/dist/workspace/symbols.d.ts.map +1 -1
- package/dist/workspace/trust/run-commits.d.ts +46 -0
- package/dist/workspace/trust/run-commits.d.ts.map +1 -0
- package/dist/workspace/trust/run-statement.d.ts +128 -0
- package/dist/workspace/trust/run-statement.d.ts.map +1 -0
- package/dist/workspace/trust/seal.d.ts +6 -1
- package/dist/workspace/trust/seal.d.ts.map +1 -1
- package/dist/workspace/trust/verify-cli.d.ts +1 -1
- package/dist/workspace/trust/verify.d.ts +16 -2
- package/dist/workspace/trust/verify.d.ts.map +1 -1
- package/dist/workspace/wip-cli.d.ts +21 -0
- package/dist/workspace/wip-cli.d.ts.map +1 -0
- package/dist/workspace/wip.d.ts +268 -0
- package/dist/workspace/wip.d.ts.map +1 -0
- package/dist/workspace/work-cli.d.ts.map +1 -1
- package/dist/workspace/work-evidence.d.ts +1 -1
- package/dist/workspace/work-evidence.d.ts.map +1 -1
- package/dist/workspace/work-size.d.ts +55 -0
- package/dist/workspace/work-size.d.ts.map +1 -0
- package/dist/workspace/workspace-kinds.schema.json +122 -0
- package/dist/workspace/write-lock-cli.d.ts +60 -0
- package/dist/workspace/write-lock-cli.d.ts.map +1 -0
- package/dist/workspace/write-lock.d.ts +152 -0
- package/dist/workspace/write-lock.d.ts.map +1 -0
- package/dist/workspace/write-scope.d.ts +6 -2
- package/dist/workspace/write-scope.d.ts.map +1 -1
- package/dist/yaml.d.ts +1 -1
- package/dist/yaml.d.ts.map +1 -1
- package/package.json +6 -1
- package/src/__fixtures__/change-set/lifecycle-plan.floci.json +59 -0
- package/src/__fixtures__/change-set/lifecycle-v1.ts.txt +4 -0
- package/src/__fixtures__/change-set/lifecycle-v2.ts.txt +4 -0
- package/src/__fixtures__/change-set/lifecycle.change-set.golden.json +95 -0
- package/src/__fixtures__/change-set/warden.change-set.golden.json +106 -0
- package/src/__fixtures__/change-set/warden.plan.json +44 -0
- package/src/__fixtures__/plan-summary/normalization-vectors.json +1593 -0
- package/src/__fixtures__/pr-loop/pr-apply-applied.note.golden.md +31 -0
- package/src/__fixtures__/pr-loop/pr-apply-refused.note.golden.md +31 -0
- package/src/__fixtures__/pr-loop/pr-plan.golden.json +127 -0
- package/src/__fixtures__/pr-loop/pr-plan.note.golden.md +37 -0
- package/src/audit/core.test.ts +15 -0
- package/src/audit/core.ts +8 -2
- package/src/audit/discover.test.ts +11 -0
- package/src/audit/discover.ts +7 -2
- package/src/change-set-bundle.test.ts +57 -0
- package/src/change-set.test.ts +215 -0
- package/src/change-set.ts +445 -0
- package/src/cli/commands/audit-opt-in.test.ts +54 -0
- package/src/cli/commands/audit.ts +29 -2
- package/src/cli/commands/build.test.ts +19 -0
- package/src/cli/commands/build.ts +3 -2
- package/src/cli/handlers/build.ts +13 -1
- package/src/cli/handlers/change-set.test.ts +56 -0
- package/src/cli/handlers/change-set.ts +44 -0
- package/src/cli/handlers/fan-out.test.ts +221 -2
- package/src/cli/handlers/fan-out.ts +165 -75
- package/src/cli/handlers/graph.ts +3 -0
- package/src/cli/handlers/operator.test.ts +21 -0
- package/src/cli/handlers/operator.ts +34 -3
- package/src/cli/handlers/pr.ts +373 -0
- package/src/cli/handlers/run.ts +1 -0
- package/src/cli/main.test.ts +20 -0
- package/src/cli/main.ts +185 -23
- package/src/cli/mcp/never-over-mcp.test.ts +101 -0
- package/src/cli/mcp/op-tools.ts +24 -2
- package/src/cli/mcp/workspace-tools.test.ts +1 -1
- package/src/cli/mcp/workspace-tools.ts +34 -6
- package/src/cli/registry.ts +63 -1
- package/src/components/auto-release.ts +1 -1
- package/src/components/capability.ts +55 -0
- package/src/components/changed-files.ts +66 -0
- package/src/components/cli-support.ts +28 -5
- package/src/components/component.schema.json +17 -0
- package/src/components/component.ts +25 -0
- package/src/components/deploy-units.ts +3 -0
- package/src/components/driver.test.ts +52 -0
- package/src/components/driver.ts +31 -13
- package/src/components/fan-out-output.ts +42 -1
- package/src/components/fan-out-record.ts +69 -0
- package/src/components/fan-out-run.test.ts +17 -0
- package/src/components/fan-out-run.ts +304 -1
- package/src/components/fan-out-support.ts +3 -0
- package/src/components/fan-out-waves.test.ts +375 -0
- package/src/components/fan-out.ts +18 -17
- package/src/components/gated-wave-pipeline.ts +82 -0
- package/src/components/index.ts +1 -0
- package/src/components/layers.ts +30 -0
- package/src/components/pr-pipeline.ts +91 -0
- package/src/components/pr-run.test.ts +205 -0
- package/src/components/pr-run.ts +280 -0
- package/src/components/promote.ts +5 -0
- package/src/components/verbs/shell.test.ts +11 -0
- package/src/components/verbs/shell.ts +7 -3
- package/src/components/wave-plan.ts +124 -0
- package/src/discovery/sandbox/bundle.ts +1 -1
- package/src/gated-waves-bundle.test.ts +62 -0
- package/src/gated-waves.test.ts +118 -0
- package/src/gated-waves.ts +240 -0
- package/src/index.ts +1 -0
- package/src/lexicon.ts +51 -0
- package/src/lifecycle/gate-ledger.ts +7 -0
- package/src/lifecycle/git.ts +102 -16
- package/src/lint/post-synth.test.ts +19 -0
- package/src/lint/post-synth.ts +19 -1
- package/src/meta/declared-imports.test.ts +1 -1
- package/src/op/activities/activity-contracts.ts +84 -0
- package/src/op/activities/change-set.ts +114 -0
- package/src/op/activities/decide.ts +3 -0
- package/src/op/activities/factory.ts +675 -0
- package/src/op/activities/index.ts +6 -0
- package/src/op/activity-contract.test.ts +21 -1
- package/src/op/activity-contract.ts +19 -9
- package/src/op/builders.ts +23 -0
- package/src/op/decide-backend.ts +5 -1
- package/src/op/decide-read-inputs.ts +33 -5
- package/src/op/factory.e2e.test.ts +232 -0
- package/src/op/factory.ts +118 -0
- package/src/op/index.ts +9 -1
- package/src/op/op-ir.test.ts +9 -0
- package/src/op/op-ir.ts +4 -0
- package/src/op/op-verb-class.ts +3 -0
- package/src/op/types.ts +8 -0
- package/src/op/work-lease-run.ts +3 -0
- package/src/plan-summary.test.ts +263 -0
- package/src/plan-summary.ts +845 -0
- package/src/pr-forge.test.ts +237 -0
- package/src/pr-forge.ts +332 -0
- package/src/pr-loop-bundle.test.ts +46 -0
- package/src/pr-loop.test.ts +171 -0
- package/src/pr-loop.ts +324 -0
- package/src/telemetry-attribution.test.ts +23 -1
- package/src/telemetry-attribution.ts +51 -0
- package/src/terraform/hcl2json.test.ts +21 -0
- package/src/terraform/hcl2json.ts +81 -0
- package/src/terraform/parse.ts +11 -74
- package/src/vendor/js-yaml-load.test.ts +115 -0
- package/src/vendor/js-yaml-load.ts +1939 -0
- package/src/workspace/__fixtures__/studio-template-84c8b21.json +1 -1
- package/src/workspace/app-kind.test.ts +196 -0
- package/src/workspace/box-cli.ts +113 -0
- package/src/workspace/box-factory.test.ts +4 -1
- package/src/workspace/box-factory.ts +37 -4
- package/src/workspace/box-listing-write.schema.json +204 -0
- package/src/workspace/box-listing.test.ts +234 -0
- package/src/workspace/box-listing.ts +324 -0
- package/src/workspace/box-publish.schema.json +498 -0
- package/src/workspace/box-publish.test.ts +204 -0
- package/src/workspace/box-publish.ts +420 -0
- package/src/workspace/box-ship.test.ts +96 -0
- package/src/workspace/broker-protocol.schema.json +186 -0
- package/src/workspace/broker-protocol.test.ts +122 -0
- package/src/workspace/broker-protocol.ts +317 -0
- package/src/workspace/builder-tiers.test.ts +146 -0
- package/src/workspace/change-set.schema.json +460 -0
- package/src/workspace/chant-migrations.e2e.test.ts +17 -5
- package/src/workspace/checks/boxes.test.ts +3 -0
- package/src/workspace/checks.ts +10 -3
- package/src/workspace/component-environments.test.ts +105 -0
- package/src/workspace/composites.schema.json +23 -4
- package/src/workspace/composites.test.ts +8 -8
- package/src/workspace/composites.ts +13 -2
- package/src/workspace/conformance/__fixture__/decisions/decision.schema.json +2 -2
- package/src/workspace/conformance/__fixtures__/reference-broker.ts +207 -0
- package/src/workspace/conformance/__writer_fixture__/answers/answer.kind.mjs +7 -2
- package/src/workspace/conformance/__writer_fixture__/answers/answer.schema.json +42 -2
- package/src/workspace/conformance/__writer_fixture__/contracts/contract.kind.mjs +37 -0
- package/src/workspace/conformance/__writer_fixture__/contracts/contract.schema.json +213 -0
- package/src/workspace/conformance/__writer_fixture__/decisions/points.json +96 -0
- package/src/workspace/conformance/__writer_fixture__/drivers/driver.kind.mjs +15 -0
- package/src/workspace/conformance/__writer_fixture__/drivers/driver.schema.json +38 -0
- package/src/workspace/conformance/__writer_fixture__/sessions/session.kind.mjs +14 -8
- package/src/workspace/conformance/__writer_fixture__/sessions/session.schema.json +187 -6
- package/src/workspace/conformance/__writer_fixture__/work/work.schema.json +25 -0
- package/src/workspace/conformance/broker.test.ts +122 -0
- package/src/workspace/conformance/broker.ts +792 -0
- package/src/workspace/conformance/conformance.e2e.test.ts +2 -1
- package/src/workspace/conformance/index.mjs +22 -1
- package/src/workspace/conformance/index.ts +5 -1
- package/src/workspace/conformance/vitest.ts +33 -1
- package/src/workspace/conformance/writer-conformance.e2e.test.ts +49 -3
- package/src/workspace/conformance/writer.test.ts +32 -2
- package/src/workspace/conformance/writer.ts +339 -28
- package/src/workspace/decide.test.ts +208 -4
- package/src/workspace/decide.ts +427 -73
- package/src/workspace/decision-points.schema.json +11 -4
- package/src/workspace/declaration.schema.json +153 -4
- package/src/workspace/declaration.ts +141 -0
- package/src/workspace/environments.ts +66 -14
- package/src/workspace/factory-rules.test.ts +62 -0
- package/src/workspace/factory-rules.ts +218 -0
- package/src/workspace/graph-cli.ts +2 -2
- package/src/workspace/graph.schema.json +67 -0
- package/src/workspace/identity.test.ts +23 -0
- package/src/workspace/init.ts +82 -2
- package/src/workspace/intent-cli.ts +26 -9
- package/src/workspace/intent-patch-id.test.ts +162 -0
- package/src/workspace/intent-record.schema.json +130 -3
- package/src/workspace/intent-record.ts +74 -28
- package/src/workspace/intent-reviews.test.ts +76 -0
- package/src/workspace/intent-squash.test.ts +213 -0
- package/src/workspace/intent-why.test.ts +5 -5
- package/src/workspace/intent.schema.json +234 -4
- package/src/workspace/intent.ts +260 -66
- package/src/workspace/json-edit.test.ts +121 -0
- package/src/workspace/json-edit.ts +142 -0
- package/src/workspace/jsonc.ts +20 -0
- package/src/workspace/kinds.ts +157 -2
- package/src/workspace/lexicon-symbols.test.ts +148 -0
- package/src/workspace/lexicon-symbols.ts +125 -0
- package/src/workspace/lineage-upgrade.test.ts +63 -0
- package/src/workspace/lineage-upgrade.ts +146 -5
- package/src/workspace/plan-summary.schema.json +155 -0
- package/src/workspace/point-answer.schema.json +42 -2
- package/src/workspace/points-cli.ts +42 -16
- package/src/workspace/points-write.schema.json +162 -4
- package/src/workspace/points.schema.json +157 -2
- package/src/workspace/points.test.ts +13 -1
- package/src/workspace/points.ts +118 -12
- package/src/workspace/pr-report.schema.json +95 -0
- package/src/workspace/profiles.test.ts +159 -0
- package/src/workspace/read-contract.test.ts +2 -2
- package/src/workspace/reason-codes.test.ts +13 -1
- package/src/workspace/reason-codes.ts +38 -4
- package/src/workspace/record-sessions.ts +9 -8
- package/src/workspace/records-amend.schema.json +78 -0
- package/src/workspace/records-cli.ts +20 -6
- package/src/workspace/records-close.schema.json +78 -0
- package/src/workspace/records-close.ts +31 -7
- package/src/workspace/records-concurrent.e2e.test.ts +135 -0
- package/src/workspace/records-concurrent.test.ts +145 -0
- package/src/workspace/records-formats.test.ts +46 -10
- package/src/workspace/records-new.schema.json +7 -0
- package/src/workspace/records-review.schema.json +78 -0
- package/src/workspace/records-sessions-write.test.ts +69 -0
- package/src/workspace/records-sessions.test.ts +22 -0
- package/src/workspace/records-write.ts +192 -25
- package/src/workspace/records.schema.json +16 -0
- package/src/workspace/records.ts +50 -9
- package/src/workspace/reference-kinds/app/package.json +10 -0
- package/src/workspace/reference-kinds/app/workspace-kinds.json +45 -0
- package/src/workspace/run-statement.schema.json +622 -0
- package/src/workspace/runs-cli.ts +343 -14
- package/src/workspace/runs-statement.test.ts +239 -0
- package/src/workspace/runs-write.schema.json +416 -5
- package/src/workspace/runs.schema.json +451 -4
- package/src/workspace/runs.test.ts +39 -0
- package/src/workspace/runs.ts +296 -35
- package/src/workspace/session-kinds.ts +3 -3
- package/src/workspace/squash.ts +198 -0
- package/src/workspace/status-contract.test.ts +5 -2
- package/src/workspace/status-gates.ts +3 -1
- package/src/workspace/status.schema.json +126 -3
- package/src/workspace/status.ts +90 -1
- package/src/workspace/symbols.ts +20 -9
- package/src/workspace/trust/run-commits.ts +115 -0
- package/src/workspace/trust/run-statement.ts +226 -0
- package/src/workspace/trust/seal.ts +8 -2
- package/src/workspace/trust/verify-cli.ts +6 -5
- package/src/workspace/trust/verify.ts +39 -6
- package/src/workspace/wip-cli.ts +97 -0
- package/src/workspace/wip-write.schema.json +504 -0
- package/src/workspace/wip.schema.json +334 -0
- package/src/workspace/wip.test.ts +294 -0
- package/src/workspace/wip.ts +753 -0
- package/src/workspace/work-cli.ts +3 -0
- package/src/workspace/work-evidence.schema.json +3 -0
- package/src/workspace/work-size.test.ts +77 -0
- package/src/workspace/work-size.ts +93 -0
- package/src/workspace/workspace-kinds.schema.json +122 -0
- package/src/workspace/write-lock-cli.ts +131 -0
- package/src/workspace/write-lock.schema.json +172 -0
- package/src/workspace/write-lock.test.ts +189 -0
- package/src/workspace/write-lock.ts +474 -0
- package/src/workspace/write-scope.test.ts +16 -1
- package/src/workspace/write-scope.ts +33 -11
- package/src/yaml.ts +31 -21
|
@@ -194,6 +194,69 @@ describe("chant workspace upgrade", () => {
|
|
|
194
194
|
expect(git(proj, ["status", "--porcelain"])).toBe("");
|
|
195
195
|
});
|
|
196
196
|
|
|
197
|
+
describe("a CI workflow a chant member builds is rebuilt with this chant (#3244)", () => {
|
|
198
|
+
const WS = JSON.stringify({ name: "proj", schema: 1, members: [{ name: "delivery", dir: "delivery", kind: "chant" }] }, null, 2) + "\n";
|
|
199
|
+
const PKG = JSON.stringify({ name: "delivery", scripts: { "ci:build": "chant build ci --lexicon github -o ../.github/workflows/ci.yml", "ci:check": "npm run ci:build && git diff --exit-code ../.github/workflows/ci.yml", "agents": "chant build agents --lexicon fountain -o ../.studio/agents.yaml" } }, null, 2) + "\n";
|
|
200
|
+
const OLD = "steps:\n - uses: actions/checkout@v4\n";
|
|
201
|
+
const NEW = "steps:\n - uses: actions/checkout@v7\n";
|
|
202
|
+
/** A chant whose github lexicon now emits @v7: `build` writes NEW where -o points. */
|
|
203
|
+
const builds = (calls: Array<{ command: string; cwd: string; args?: readonly string[] }>, output = NEW): ChantRunner => async (command, cwd, args) => {
|
|
204
|
+
calls.push({ command, cwd, args });
|
|
205
|
+
const o = args?.indexOf("-o") ?? -1;
|
|
206
|
+
if (o >= 0) put(cwd, args![o + 1], output);
|
|
207
|
+
return { exitCode: 0, output: "" };
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
beforeEach(() => {
|
|
211
|
+
release("v2.0.0", { "chant.workspace.json": WS, "delivery/chant.config.ts": "export default {};\n", "delivery/package.json": PKG, ".github/workflows/ci.yml": OLD });
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
test("an upgrade to the same version puts the rebuilt workflow in the patch, and only the CI workflow", async () => {
|
|
215
|
+
// A box planted at v2.0.0 with the chant of then.
|
|
216
|
+
const port = ledger();
|
|
217
|
+
const staged0 = await upgradeCommand({ root: proj, to: "v2.0.0", runChant: passing, ledger: port, now: "2026-10-03T00:00:00.000Z" });
|
|
218
|
+
port.approve(staged0.staged!.digest, "2026-10-03T00:01:00.000Z");
|
|
219
|
+
expect((await upgradeCommand({ root: proj, to: "v2.0.0", runChant: passing, ledger: port, now: "2026-10-03T00:02:00.000Z" })).outcome).toBe("applied");
|
|
220
|
+
commitProject("at v2");
|
|
221
|
+
expect(read(proj, ".github/workflows/ci.yml")).toBe(OLD);
|
|
222
|
+
|
|
223
|
+
// chant is upgraded; the template is not. The workflow ci.ts builds now differs.
|
|
224
|
+
const calls: Array<{ command: string; cwd: string; args?: readonly string[] }> = [];
|
|
225
|
+
const staged = await stageUpgrade({ root: proj, to: "v2.0.0", runChant: builds(calls) });
|
|
226
|
+
try {
|
|
227
|
+
expect(staged.workflows).toEqual([{ member: "delivery", script: "ci:build", path: ".github/workflows/ci.yml", command: "chant build ci --lexicon github -o ../.github/workflows/ci.yml", status: "rebuilt" }]);
|
|
228
|
+
expect(calls[0]).toEqual({ command: "build", cwd: join(staged.worktreeProject, "delivery"), args: ["ci", "--lexicon", "github", "-o", "../.github/workflows/ci.yml"] });
|
|
229
|
+
// The agents script writes no CI workflow, so it is not run.
|
|
230
|
+
expect(calls.some((c) => c.args?.includes("agents"))).toBe(false);
|
|
231
|
+
expect(staged.changed).toBe(true);
|
|
232
|
+
expect(staged.changedPaths).toEqual([".github/workflows/ci.yml"]);
|
|
233
|
+
expect(staged.governance?.paths).toEqual([".github/workflows/ci.yml"]);
|
|
234
|
+
expect(read(proj, ".github/workflows/ci.yml")).toBe(OLD);
|
|
235
|
+
} finally {
|
|
236
|
+
staged.dispose();
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Once it is committed as built, the next upgrade finds nothing to do.
|
|
240
|
+
put(proj, ".github/workflows/ci.yml", NEW);
|
|
241
|
+
commitProject("ci:build");
|
|
242
|
+
const again = await stageUpgrade({ root: proj, to: "v2.0.0", runChant: builds([]) });
|
|
243
|
+
try {
|
|
244
|
+
expect(again.workflows.map((w) => w.status)).toEqual(["unchanged"]);
|
|
245
|
+
expect(again.changed).toBe(false);
|
|
246
|
+
} finally {
|
|
247
|
+
again.dispose();
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
test("a workflow that does not build fails the build check and stays as it was", async () => {
|
|
252
|
+
const failing: ChantRunner = async (_command, _cwd, args) => (args?.length ? { exitCode: 1, output: "cannot find @intentius/chant-lexicon-github\n" } : { exitCode: 0, output: "" });
|
|
253
|
+
const result = await upgradeCommand({ root: proj, to: "v2.0.0", runChant: failing });
|
|
254
|
+
expect(result.outcome).toBe("checks-failed");
|
|
255
|
+
expect(result.staged!.workflows.map((w) => w.status)).toEqual(["failed"]);
|
|
256
|
+
expect(result.staged!.checks).toEqual(expect.arrayContaining([expect.objectContaining({ name: "build", status: "failed", member: "delivery", detail: expect.stringMatching(/\.github\/workflows\/ci\.yml could not be rebuilt[\s\S]*cannot find/) })]));
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
|
|
197
260
|
test("gates on the patch digest, then applies exactly the approved patch", async () => {
|
|
198
261
|
release("v2.0.0", { "README.md": "starter v2\n" });
|
|
199
262
|
const port = ledger();
|
|
@@ -21,6 +21,9 @@
|
|
|
21
21
|
* 4. Merge per file (ws-005): an edited file takes the new version only when
|
|
22
22
|
* every hunk merges cleanly. Otherwise it stays as it was, with one manual
|
|
23
23
|
* step. The worktree never holds conflict markers.
|
|
24
|
+
* Then rebuild each CI workflow a chant member's package.json builds with
|
|
25
|
+
* `chant build ... -o <workflow>` (#3244), with the chant doing the
|
|
26
|
+
* upgrade, so the committed workflow follows that chant's composites.
|
|
24
27
|
* 5. Check the worktree: `chant build` and `chant lint` when the project is a
|
|
25
28
|
* chant project, and the lineage checks of `chant workspace check`.
|
|
26
29
|
* 6. Bind the gate to the digest of the resulting patch: the pending fact and
|
|
@@ -34,7 +37,7 @@
|
|
|
34
37
|
*/
|
|
35
38
|
|
|
36
39
|
import { execFileSync, spawn } from "node:child_process";
|
|
37
|
-
import { chmodSync, existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
|
|
40
|
+
import { chmodSync, existsSync, lstatSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
|
|
38
41
|
import { tmpdir } from "node:os";
|
|
39
42
|
import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
40
43
|
import { computePlanDigest } from "../lifecycle/plan-digest";
|
|
@@ -64,6 +67,7 @@ import { pathsInsideNested } from "./nesting";
|
|
|
64
67
|
import { carryParameters, readManifest, substituteParameters } from "./template-manifest";
|
|
65
68
|
import { repinSubstituted, type RepinnedRecord } from "./template-pins";
|
|
66
69
|
import { workingTree } from "./tree";
|
|
70
|
+
import { splitCommandLine } from "./checks/generated";
|
|
67
71
|
|
|
68
72
|
/** The kind the patch digest is taken under, so it never collides with another kind of plan. */
|
|
69
73
|
export const UPGRADE_PLAN_KIND = "workspace-upgrade";
|
|
@@ -86,22 +90,26 @@ export interface UpgradeCheck {
|
|
|
86
90
|
member?: string;
|
|
87
91
|
}
|
|
88
92
|
|
|
89
|
-
/**
|
|
90
|
-
|
|
93
|
+
/**
|
|
94
|
+
* Runs `chant build` or `chant lint` in a directory, with `args` after the
|
|
95
|
+
* command when given (a workflow rebuild's `ci --lexicon github -o <file>`,
|
|
96
|
+
* #3244).
|
|
97
|
+
*/
|
|
98
|
+
export type ChantRunner = (command: "build" | "lint", cwd: string, args?: readonly string[]) => Promise<{ exitCode: number; output: string }>;
|
|
91
99
|
|
|
92
100
|
/**
|
|
93
101
|
* The default runner: this same chant, in a child process. The child sees the
|
|
94
102
|
* worktree's sources and resolves packages the way the project does, since the
|
|
95
103
|
* worktree sits inside the project.
|
|
96
104
|
*/
|
|
97
|
-
export const spawnChant: ChantRunner = (command, cwd) =>
|
|
105
|
+
export const spawnChant: ChantRunner = (command, cwd, args = []) =>
|
|
98
106
|
new Promise((resolvePromise, reject) => {
|
|
99
107
|
const entry = process.argv[1];
|
|
100
108
|
if (!entry) {
|
|
101
109
|
reject(new UpgradeError("cannot find the chant entry point to run build and lint in the worktree"));
|
|
102
110
|
return;
|
|
103
111
|
}
|
|
104
|
-
const child = spawn(process.execPath, [...process.execArgv, entry, command], { cwd, stdio: ["ignore", "pipe", "pipe"], env: process.env });
|
|
112
|
+
const child = spawn(process.execPath, [...process.execArgv, entry, command, ...args], { cwd, stdio: ["ignore", "pipe", "pipe"], env: process.env });
|
|
105
113
|
const out: Buffer[] = [];
|
|
106
114
|
child.stdout.on("data", (c: Buffer) => out.push(c));
|
|
107
115
|
child.stderr.on("data", (c: Buffer) => out.push(c));
|
|
@@ -139,6 +147,121 @@ export interface UpgradeOptions {
|
|
|
139
147
|
runChant?: ChantRunner;
|
|
140
148
|
}
|
|
141
149
|
|
|
150
|
+
/**
|
|
151
|
+
* A CI workflow a chant member's package.json builds, and what rebuilding it
|
|
152
|
+
* did (#3244). `rebuilt`: the workflow chant builds now differs from the one
|
|
153
|
+
* committed, and the patch carries the new one. `unchanged`: it is the same.
|
|
154
|
+
* `failed`: the build failed, the file is left as the merge left it, and the
|
|
155
|
+
* upgrade's `build` check fails with the output.
|
|
156
|
+
*/
|
|
157
|
+
export interface RebuiltWorkflow {
|
|
158
|
+
/** The chant member whose package.json script builds it. */
|
|
159
|
+
member: string;
|
|
160
|
+
/** The script's name, such as `ci:build`. */
|
|
161
|
+
script: string;
|
|
162
|
+
/** The workflow, relative to the repository root. */
|
|
163
|
+
path: string;
|
|
164
|
+
/** The command line, as the script has it. */
|
|
165
|
+
command: string;
|
|
166
|
+
status: "rebuilt" | "unchanged" | "failed";
|
|
167
|
+
/** The tail of the build's output, when it failed. */
|
|
168
|
+
detail?: string;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/** A CI workflow path a forge reads, relative to the repository root. The governance list's pipeline entries. */
|
|
172
|
+
const CI_WORKFLOW = [/(^|\/)\.github\/workflows\/[^/]+\.ya?ml$/, /(^|\/)\.forgejo\/workflows\/[^/]+\.ya?ml$/, /(^|\/)\.gitea\/workflows\/[^/]+\.ya?ml$/, /(^|\/)\.gitlab-ci\.ya?ml$/];
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* The CI workflows the chant members under `worktreeProject` build: each
|
|
176
|
+
* package.json script that is one `chant build ... -o <file>` command (no
|
|
177
|
+
* shell, no `&&`), whose output is a committed CI workflow inside the scope.
|
|
178
|
+
* The studio kit's template has `"ci:build": "chant build ci --lexicon github
|
|
179
|
+
* -o ../.github/workflows/ci.yml"` in delivery/, and its CI fails when the
|
|
180
|
+
* committed workflow differs from what ci/ci.ts builds.
|
|
181
|
+
*/
|
|
182
|
+
function workflowBuilds(worktree: string, worktreeProject: string, scopeRepoPath: string): Array<{ member: string; script: string; command: string; args: string[]; abs: string; path: string }> {
|
|
183
|
+
const out: Array<{ member: string; script: string; command: string; args: string[]; abs: string; path: string }> = [];
|
|
184
|
+
for (const member of chantMemberDirs(worktreeProject)) {
|
|
185
|
+
const dir = member === "." ? worktreeProject : join(worktreeProject, member);
|
|
186
|
+
let scripts: Record<string, unknown>;
|
|
187
|
+
try {
|
|
188
|
+
scripts = (JSON.parse(readFileSync(join(dir, "package.json"), "utf-8")) as { scripts?: Record<string, unknown> }).scripts ?? {};
|
|
189
|
+
} catch {
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
for (const [script, line] of Object.entries(scripts)) {
|
|
193
|
+
if (typeof line !== "string") continue;
|
|
194
|
+
const words = splitCommandLine(line);
|
|
195
|
+
if (!words || words[0] !== "chant" || words[1] !== "build") continue;
|
|
196
|
+
const flag = words.findIndex((w) => w === "-o" || w === "--output");
|
|
197
|
+
const target = flag >= 0 ? words[flag + 1] : words.find((w) => w.startsWith("--output="))?.slice("--output=".length);
|
|
198
|
+
if (!target) continue;
|
|
199
|
+
const abs = resolve(dir, target);
|
|
200
|
+
const path = relative(worktree, abs).split(sep).join("/");
|
|
201
|
+
if (path.startsWith("../") || !CI_WORKFLOW.some((re) => re.test(path))) continue;
|
|
202
|
+
if (scopeRepoPath !== "." && !path.startsWith(`${scopeRepoPath}/`)) continue;
|
|
203
|
+
if (!existsSync(abs)) continue;
|
|
204
|
+
out.push({ member, script, command: line, args: words.slice(2), abs, path });
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return out;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Rebuild the CI workflows {@link workflowBuilds} finds (#3244), each in its
|
|
212
|
+
* member's directory of the staging worktree with that member's node_modules
|
|
213
|
+
* linked in from the project. A workflow is built from the member's sources
|
|
214
|
+
* through the lexicon's composites, so upgrading chant can change it with no
|
|
215
|
+
* change to the sources (#2621 moved Checkout and SetupNode from v4 to v7),
|
|
216
|
+
* and a committed copy then fails the project's own ci:check. Rebuilding it
|
|
217
|
+
* here puts the new workflow in the patch the gate approves. The links are
|
|
218
|
+
* removed before the patch is taken. A build that fails leaves the file as
|
|
219
|
+
* the merge left it.
|
|
220
|
+
*/
|
|
221
|
+
async function rebuildWorkflows(root: string, worktree: string, worktreeProject: string, scopeRepoPath: string, run: ChantRunner): Promise<RebuiltWorkflow[]> {
|
|
222
|
+
const builds = workflowBuilds(worktree, worktreeProject, scopeRepoPath);
|
|
223
|
+
if (builds.length === 0) return [];
|
|
224
|
+
const linked: string[] = [];
|
|
225
|
+
const results: RebuiltWorkflow[] = [];
|
|
226
|
+
try {
|
|
227
|
+
for (const member of new Set(builds.map((b) => b.member))) {
|
|
228
|
+
if (member === ".") continue;
|
|
229
|
+
const from = join(root, member, "node_modules");
|
|
230
|
+
const to = join(worktreeProject, member, "node_modules");
|
|
231
|
+
if (existsSync(from) && !existsSync(to) && existsSync(dirname(to))) {
|
|
232
|
+
symlinkSync(from, to, "dir");
|
|
233
|
+
linked.push(to);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
for (const b of builds) {
|
|
237
|
+
const before = readFileSync(b.abs);
|
|
238
|
+
const r = await run("build", b.member === "." ? worktreeProject : join(worktreeProject, b.member), b.args);
|
|
239
|
+
const base = { member: b.member, script: b.script, path: b.path, command: b.command };
|
|
240
|
+
if (r.exitCode !== 0) {
|
|
241
|
+
writeFileSync(b.abs, before);
|
|
242
|
+
results.push({ ...base, status: "failed", detail: tail(r.output) });
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
const after = existsSync(b.abs) ? readFileSync(b.abs) : null;
|
|
246
|
+
if (after === null) {
|
|
247
|
+
writeFileSync(b.abs, before);
|
|
248
|
+
results.push({ ...base, status: "failed", detail: `\`${b.command}\` exited 0 and wrote no ${b.path}` });
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
results.push({ ...base, status: after.equals(before) ? "unchanged" : "rebuilt" });
|
|
252
|
+
}
|
|
253
|
+
} finally {
|
|
254
|
+
for (const l of linked) {
|
|
255
|
+
try {
|
|
256
|
+
if (lstatSync(l).isSymbolicLink()) unlinkSync(l);
|
|
257
|
+
} catch {
|
|
258
|
+
// Already gone.
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return results;
|
|
263
|
+
}
|
|
264
|
+
|
|
142
265
|
export interface GovernanceChange {
|
|
143
266
|
/** Changed governance paths, relative to the repository root. */
|
|
144
267
|
paths: string[];
|
|
@@ -166,6 +289,8 @@ export interface StagedUpgrade {
|
|
|
166
289
|
migrations: string[];
|
|
167
290
|
/** The migrations chant ships (./chant-migrations.ts) that found something to move, applied or not. */
|
|
168
291
|
chantMigrations: ChantMigrationReport[];
|
|
292
|
+
/** The CI workflows a chant member builds, rebuilt with this chant before the patch was taken (#3244). */
|
|
293
|
+
workflows: RebuiltWorkflow[];
|
|
169
294
|
written: string[];
|
|
170
295
|
merged: string[];
|
|
171
296
|
removed: string[];
|
|
@@ -694,6 +819,10 @@ export async function stageUpgrade(options: UpgradeOptions): Promise<StagedUpgra
|
|
|
694
819
|
writeLock(worktreeProject, next);
|
|
695
820
|
const lockText = renderLock(next);
|
|
696
821
|
|
|
822
|
+
// The CI workflows a chant member builds, rebuilt with this chant (#3244),
|
|
823
|
+
// before the patch is taken so the gate approves them with the rest.
|
|
824
|
+
const workflows = lineage.kind === "template" ? await rebuildWorkflows(root, worktree, worktreeProject, scopeRepoPath, options.runChant ?? spawnChant) : [];
|
|
825
|
+
|
|
697
826
|
// The patch, taken before anything else runs in the worktree.
|
|
698
827
|
gitOut(worktree, ["add", "-A"]);
|
|
699
828
|
if (!lockTracked) gitOut(worktree, ["rm", "--cached", "-q", "--ignore-unmatch", "--", lockRepoPath]);
|
|
@@ -730,6 +859,14 @@ export async function stageUpgrade(options: UpgradeOptions): Promise<StagedUpgra
|
|
|
730
859
|
|
|
731
860
|
// 5. Checks.
|
|
732
861
|
const checks: UpgradeCheck[] = [];
|
|
862
|
+
for (const w of workflows.filter((w) => w.status === "failed")) {
|
|
863
|
+
checks.push({
|
|
864
|
+
name: "build",
|
|
865
|
+
status: "failed",
|
|
866
|
+
member: w.member,
|
|
867
|
+
detail: `${w.path} could not be rebuilt with \`${w.command}\` (the ${w.script} script), so it may differ from what this chant builds:\n${w.detail ?? ""}`,
|
|
868
|
+
});
|
|
869
|
+
}
|
|
733
870
|
for (const m of chantMigrations.filter((m) => !m.applied)) {
|
|
734
871
|
checks.push({
|
|
735
872
|
name: "migration",
|
|
@@ -783,6 +920,7 @@ export async function stageUpgrade(options: UpgradeOptions): Promise<StagedUpgra
|
|
|
783
920
|
...(upstream.commit ? { commit: { ...(lineage.address?.commit ? { from: lineage.address.commit } : {}), to: upstream.commit } } : {}),
|
|
784
921
|
migrations: [...plan.chain.map((m) => m.migration.id), ...chantMigrations.filter((m) => m.applied).map((m) => m.id)],
|
|
785
922
|
chantMigrations,
|
|
923
|
+
workflows,
|
|
786
924
|
written: result.written,
|
|
787
925
|
merged: result.merged,
|
|
788
926
|
removed: result.removed,
|
|
@@ -885,6 +1023,9 @@ export function describeStaged(staged: StagedUpgrade): string[] {
|
|
|
885
1023
|
for (const n of m.notMoved) lines.push(` not moved: ${n.what} -> ${n.where}`);
|
|
886
1024
|
for (const c of m.conflicts) lines.push(` conflict: ${at(c.path)}: ${c.reason}`);
|
|
887
1025
|
}
|
|
1026
|
+
for (const w of staged.workflows) {
|
|
1027
|
+
if (w.status !== "unchanged") lines.push(` workflow ${w.status === "rebuilt" ? "rebuilt" : "not rebuilt"}: ${w.path} (${w.script}: ${w.command})`);
|
|
1028
|
+
}
|
|
888
1029
|
for (const p of staged.written) lines.push(` updated: ${at(p)}`);
|
|
889
1030
|
for (const p of staged.merged) lines.push(` merged: ${at(p)}`);
|
|
890
1031
|
for (const p of staged.removed) lines.push(` removed: ${at(p)}`);
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://intentius.io/chant/schemas/workspace/plan-summary/v1/plan-summary.schema.json",
|
|
4
|
+
"title": "plan summary",
|
|
5
|
+
"description": "The grouped plan summary (#3188): a change-set document's members, or one member's instances, grouped by their normalized changes, with every destroy, replacement, failure and hole by name. Written by `chant change-set summary --format json` and by groupChangeSet in @intentius/chant/plan-summary. Reviewers read it; no gate binds it. Version 1 of the workspace read contract. Readers ignore fields they do not know; a field is only ever added within a version.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["$schema", "contract", "changeSet", "unit", "units", "groups", "failed", "destroys", "holes", "imports", "forgets", "sideEffects"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"$schema": { "const": "https://intentius.io/chant/schemas/workspace/plan-summary/v1/plan-summary.schema.json" },
|
|
10
|
+
"contract": { "const": 1 },
|
|
11
|
+
"changeSet": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"pattern": "^(?:jcs1-)?sha256:[0-9a-f]{64}$",
|
|
14
|
+
"description": "The digest of the change-set document summarized."
|
|
15
|
+
},
|
|
16
|
+
"unit": {
|
|
17
|
+
"enum": ["member", "instance"],
|
|
18
|
+
"description": "member: each unit is a member of the document. instance: each unit is one resource instance of the document's one member."
|
|
19
|
+
},
|
|
20
|
+
"units": {
|
|
21
|
+
"type": "integer",
|
|
22
|
+
"minimum": 0,
|
|
23
|
+
"description": "Members, failed ones included, or the changing instances."
|
|
24
|
+
},
|
|
25
|
+
"groups": {
|
|
26
|
+
"type": "array",
|
|
27
|
+
"description": "Largest first. For instances, sorted by resource first.",
|
|
28
|
+
"items": { "$ref": "#/$defs/group" }
|
|
29
|
+
},
|
|
30
|
+
"failed": {
|
|
31
|
+
"type": "array",
|
|
32
|
+
"description": "Members that failed to plan. None is in a group.",
|
|
33
|
+
"items": {
|
|
34
|
+
"type": "object",
|
|
35
|
+
"required": ["member", "reason"],
|
|
36
|
+
"properties": {
|
|
37
|
+
"member": { "type": "string" },
|
|
38
|
+
"scope": { "type": "string" },
|
|
39
|
+
"reason": { "type": "string" }
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"destroys": {
|
|
44
|
+
"type": "array",
|
|
45
|
+
"description": "Every delete and replace in the document, failed members' included, sorted by member and address.",
|
|
46
|
+
"items": { "$ref": "#/$defs/destroy" }
|
|
47
|
+
},
|
|
48
|
+
"imports": {
|
|
49
|
+
"type": "array",
|
|
50
|
+
"description": "Every entry that imports an object into state, sorted by member and address. An import is not a destroy.",
|
|
51
|
+
"items": { "$ref": "#/$defs/import" }
|
|
52
|
+
},
|
|
53
|
+
"forgets": {
|
|
54
|
+
"type": "array",
|
|
55
|
+
"description": "Every forget: the plan stops tracking the object and leaves it running. Never in destroys, and a destroy is never here.",
|
|
56
|
+
"items": { "$ref": "#/$defs/forget" }
|
|
57
|
+
},
|
|
58
|
+
"sideEffects": {
|
|
59
|
+
"type": "array",
|
|
60
|
+
"description": "Every provider-defined action an apply runs (Terraform actions blocks), sorted by member and address.",
|
|
61
|
+
"items": { "$ref": "#/$defs/sideEffect" }
|
|
62
|
+
},
|
|
63
|
+
"holes": {
|
|
64
|
+
"type": "array",
|
|
65
|
+
"description": "Every address a member's planner could not read.",
|
|
66
|
+
"items": {
|
|
67
|
+
"type": "object",
|
|
68
|
+
"required": ["member", "address", "reason"],
|
|
69
|
+
"properties": {
|
|
70
|
+
"member": { "type": "string" },
|
|
71
|
+
"address": { "type": "string" },
|
|
72
|
+
"type": { "type": "string" },
|
|
73
|
+
"reason": { "type": "string" }
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
"$defs": {
|
|
79
|
+
"action": { "enum": ["create", "update", "replace", "delete", "read", "no-op", "forget"] },
|
|
80
|
+
"import": {
|
|
81
|
+
"type": "object",
|
|
82
|
+
"required": ["member", "address", "type", "action"],
|
|
83
|
+
"properties": {
|
|
84
|
+
"member": { "type": "string" },
|
|
85
|
+
"address": { "type": "string" },
|
|
86
|
+
"type": { "type": "string" },
|
|
87
|
+
"action": { "$ref": "#/$defs/action", "description": "What else the plan does to the object; no-op when the import changes nothing." }
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
"forget": {
|
|
91
|
+
"type": "object",
|
|
92
|
+
"required": ["member", "address", "type"],
|
|
93
|
+
"properties": {
|
|
94
|
+
"member": { "type": "string" },
|
|
95
|
+
"address": { "type": "string" },
|
|
96
|
+
"type": { "type": "string" },
|
|
97
|
+
"deposed": { "type": "string" }
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
"sideEffect": {
|
|
101
|
+
"type": "object",
|
|
102
|
+
"required": ["member", "address", "type"],
|
|
103
|
+
"properties": {
|
|
104
|
+
"member": { "type": "string" },
|
|
105
|
+
"address": { "type": "string", "description": "The invocation's address, or its action type when the planner gives none." },
|
|
106
|
+
"type": { "type": "string" },
|
|
107
|
+
"trigger": { "type": "string", "description": "The resource whose lifecycle triggers it." },
|
|
108
|
+
"event": { "type": "string" }
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
"destroy": {
|
|
112
|
+
"type": "object",
|
|
113
|
+
"required": ["member", "address", "type", "action"],
|
|
114
|
+
"properties": {
|
|
115
|
+
"member": { "type": "string" },
|
|
116
|
+
"address": { "type": "string", "description": "The real address, never normalized." },
|
|
117
|
+
"type": { "type": "string" },
|
|
118
|
+
"action": { "enum": ["delete", "replace"] },
|
|
119
|
+
"deposed": { "type": "string" }
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
"change": {
|
|
123
|
+
"type": "object",
|
|
124
|
+
"required": ["line", "action", "count"],
|
|
125
|
+
"properties": {
|
|
126
|
+
"line": { "type": "string", "description": "The action's symbol, the normalized address and, for an update or replace, the attributes it writes. Values are never printed." },
|
|
127
|
+
"action": { "$ref": "#/$defs/action" },
|
|
128
|
+
"count": { "type": "integer", "minimum": 1, "description": "How many times one unit makes this change." },
|
|
129
|
+
"differsFrom": { "type": "string", "description": "The baseline group whose change at the same address and action this one differs from." },
|
|
130
|
+
"differsIn": { "type": "array", "items": { "type": "string" }, "description": "The attributes it differs in." }
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
"group": {
|
|
134
|
+
"type": "object",
|
|
135
|
+
"required": ["id", "units", "outlier", "noChanges", "changes", "destroys"],
|
|
136
|
+
"properties": {
|
|
137
|
+
"id": {
|
|
138
|
+
"type": "string",
|
|
139
|
+
"pattern": "^[0-9a-f]{12}$",
|
|
140
|
+
"description": "Twelve hex characters of computePlanDigest(\"plan-summary-group\", { resource, changes }) over the group's sorted normalized changes. The same change gets the same id in every run, so a report can link one group across commits. A change to the normalization rules can change it."
|
|
141
|
+
},
|
|
142
|
+
"resource": { "type": "string", "description": "For instance groups, the expansion: the address with its instance keys removed." },
|
|
143
|
+
"units": { "type": "array", "items": { "type": "string" }, "description": "Member names or instance addresses, sorted." },
|
|
144
|
+
"outlier": { "type": "boolean", "description": "A group of one beside other groups of the same expansion." },
|
|
145
|
+
"noChanges": { "type": "boolean" },
|
|
146
|
+
"changes": { "type": "array", "items": { "$ref": "#/$defs/change" } },
|
|
147
|
+
"extends": { "type": "string", "description": "The group whose whole change this one contains." },
|
|
148
|
+
"plus": { "type": "array", "items": { "$ref": "#/$defs/change" }, "description": "What it adds to that group's change." },
|
|
149
|
+
"destroys": { "type": "array", "items": { "$ref": "#/$defs/destroy" }, "description": "Every delete and replace a unit of this group makes. Each is also in the top-level destroys." },
|
|
150
|
+
"sideEffects": { "type": "array", "items": { "$ref": "#/$defs/sideEffect" }, "description": "Every triggered action a unit of this group runs." },
|
|
151
|
+
"provisional": { "const": true, "description": "Its units are provisional plans, planned before what they read applied. Part of the id, so they never share a group with real plans. Absent on a group of real plans." }
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
3
|
"$id": "urn:intentius:chant:point-answer:1",
|
|
4
4
|
"title": "Decision point answer front matter",
|
|
5
|
-
"description": "The front matter of one answer to a decision point (ws-058, #2739), as `chant workspace points ask` and `points answer` write it into the records directory of a record kind with an `answers` block. One record per point, declaration and inputs: its id is the point's name and the first 12 hex digits of the inputs hash, so the same question is answered once. A table's answer is `answered`; a model's answer at or above its threshold is `proposed` until a person confirms it; a question no decider before the quorum answered is `escalated`, open for people. A workspace copies this file next to its answer kind, as reference-workspace/answers/ does. Values stay within what YAML and JSON share. Fields other than these must start with x-.",
|
|
5
|
+
"description": "The front matter of one answer to a decision point (ws-058, #2739), as `chant workspace points ask` and `points answer` write it into the records directory of a record kind with an `answers` block. One record per point, declaration and inputs: its id is the point's name and the first 12 hex digits of the inputs hash, so the same question is answered once. A table's answer is `answered`; a model's answer at or above its threshold is `proposed` until a person confirms it; a question no decider before the quorum answered is `escalated`, open for people. An answer never changes in place: `points retract` escalates the question to people again and moves the answer into `retractions` (#3351, ws-084). An ad-hoc point's answer keeps the question and candidates its ask gave as `asked`, and they are part of the inputs hash (#3403). A workspace copies this file next to its answer kind, as reference-workspace/answers/ does. Values stay within what YAML and JSON share. Fields other than these must start with x-.",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"additionalProperties": false,
|
|
8
8
|
"patternProperties": { "^x-": {} },
|
|
@@ -14,6 +14,21 @@
|
|
|
14
14
|
"point_version": { "$ref": "#/definitions/sha256", "description": "sha256 of the point's declaration when it was asked. Editing the question or any decider changes it." },
|
|
15
15
|
"question_type": { "enum": ["noul", "choice", "score"] },
|
|
16
16
|
"candidates": { "type": "array", "minItems": 2, "items": { "type": ["string", "boolean"] }, "description": "The answers the question allowed: true and false, a choice's options, or a score's levels." },
|
|
17
|
+
"asked": {
|
|
18
|
+
"type": "object",
|
|
19
|
+
"description": "An ad-hoc point's question as its ask gave it (`points ask --candidates`, #3403): its text, and its criteria in the point's question type's shape, from which candidates come. People's answer is one of them.",
|
|
20
|
+
"required": ["question", "criteria"],
|
|
21
|
+
"properties": {
|
|
22
|
+
"question": { "type": "string", "minLength": 1 },
|
|
23
|
+
"criteria": {
|
|
24
|
+
"oneOf": [
|
|
25
|
+
{ "type": "object", "minProperties": 2, "maxProperties": 255, "additionalProperties": { "type": "string" } },
|
|
26
|
+
{ "type": "array", "minItems": 2, "maxItems": 10, "uniqueItems": true, "items": { "type": "string", "minLength": 1 } }
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"additionalProperties": false
|
|
31
|
+
},
|
|
17
32
|
"inputs": { "type": "object", "description": "The state the deciders saw, input name to value." },
|
|
18
33
|
"inputs_hash": { "$ref": "#/definitions/sha256", "description": "sha256 of the point, its version and its inputs. The same hash is answered once." },
|
|
19
34
|
"constrains": { "type": "array", "items": { "type": "string", "minLength": 1 }, "description": "What the question is about, such as a work item's id." },
|
|
@@ -36,12 +51,20 @@
|
|
|
36
51
|
"probabilities": { "$ref": "#/definitions/probabilities" },
|
|
37
52
|
"confidence": { "$ref": "#/definitions/unit" },
|
|
38
53
|
"threshold": { "$ref": "#/definitions/unit" },
|
|
54
|
+
"reason": { "type": "string", "minLength": 1, "description": "model: the model's own explanation of its answer, when the backend gave one (#3345). Kept when a person confirms the proposal; moved into the escalations as model_reason when people answer otherwise." },
|
|
39
55
|
"escalations": {
|
|
40
56
|
"type": "array",
|
|
41
57
|
"description": "The deciders asked before the one that answered, or before the quorum, and why each did not answer.",
|
|
42
58
|
"items": { "$ref": "#/definitions/escalation" }
|
|
43
59
|
},
|
|
44
60
|
"answered_by": { "type": "array", "minItems": 1, "items": { "type": "string", "minLength": 1 }, "description": "The people who answered or confirmed it." },
|
|
61
|
+
"note": { "type": "string", "minLength": 1, "description": "What the people who answered wrote with their answer (`points answer --note`, #3351). Moved into the retraction when the answer is retracted." },
|
|
62
|
+
"relayed_by": { "type": "string", "minLength": 1, "description": "Who carried the answer to chant for the people in answered_by (`points answer --relayed-by`, #3402), such as a follower relaying a person's answer through hud. It does not count toward the quorum. Moved into the retraction as answer_relayed_by when the answer is retracted." },
|
|
63
|
+
"retractions": {
|
|
64
|
+
"type": "array",
|
|
65
|
+
"description": "Answers people took back, oldest first (`points retract`, #3351): each answer as it was, and who retracted it, when and why. A retracted question is escalated to people again.",
|
|
66
|
+
"items": { "$ref": "#/definitions/retraction" }
|
|
67
|
+
},
|
|
45
68
|
"asked_on": { "$ref": "#/definitions/date" },
|
|
46
69
|
"answered_on": { "$ref": "#/definitions/date" },
|
|
47
70
|
"source": {
|
|
@@ -76,6 +99,22 @@
|
|
|
76
99
|
"unit": { "type": "number", "minimum": 0, "maximum": 1 },
|
|
77
100
|
"date": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" },
|
|
78
101
|
"probabilities": { "type": "object", "additionalProperties": { "$ref": "#/definitions/unit" } },
|
|
102
|
+
"retraction": {
|
|
103
|
+
"type": "object",
|
|
104
|
+
"required": ["answer", "decider", "by", "on"],
|
|
105
|
+
"properties": {
|
|
106
|
+
"answer": { "type": ["string", "boolean"], "description": "The answer retracted." },
|
|
107
|
+
"decider": { "type": "object", "required": ["kind"], "properties": { "kind": { "enum": ["table", "model", "quorum"] } }, "description": "Who gave it: the record's decider as it was." },
|
|
108
|
+
"answered_by": { "type": "array", "items": { "type": "string", "minLength": 1 } },
|
|
109
|
+
"answered_on": { "$ref": "#/definitions/date" },
|
|
110
|
+
"answer_note": { "type": "string", "minLength": 1, "description": "The note the answer carried." },
|
|
111
|
+
"answer_relayed_by": { "type": "string", "minLength": 1, "description": "Who relayed the answer (#3402)." },
|
|
112
|
+
"by": { "type": "array", "minItems": 1, "items": { "type": "string", "minLength": 1 }, "description": "Who retracted it." },
|
|
113
|
+
"on": { "$ref": "#/definitions/date" },
|
|
114
|
+
"note": { "type": "string", "minLength": 1, "description": "Why it was retracted (`points retract --note`)." }
|
|
115
|
+
},
|
|
116
|
+
"additionalProperties": false
|
|
117
|
+
},
|
|
79
118
|
"escalation": {
|
|
80
119
|
"type": "object",
|
|
81
120
|
"required": ["kind", "reason"],
|
|
@@ -87,7 +126,8 @@
|
|
|
87
126
|
"answer": { "type": ["string", "boolean", "null"] },
|
|
88
127
|
"probabilities": { "$ref": "#/definitions/probabilities" },
|
|
89
128
|
"confidence": { "$ref": "#/definitions/unit" },
|
|
90
|
-
"threshold": { "$ref": "#/definitions/unit" }
|
|
129
|
+
"threshold": { "$ref": "#/definitions/unit" },
|
|
130
|
+
"model_reason": { "type": "string", "minLength": 1, "description": "model: the model's own explanation of the answer it gave, when the backend gave one (#3345). reason is why the decider did not answer." }
|
|
91
131
|
},
|
|
92
132
|
"additionalProperties": false
|
|
93
133
|
}
|