@intentius/chant 0.90.0 → 0.93.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/commands/lint.d.ts.map +1 -1
- package/dist/cli/handlers/components.d.ts +8 -0
- package/dist/cli/handlers/components.d.ts.map +1 -1
- package/dist/cli/handlers/graph.d.ts.map +1 -1
- package/dist/cli/handlers/operator.d.ts +20 -0
- package/dist/cli/handlers/operator.d.ts.map +1 -1
- package/dist/cli/handlers/run.d.ts.map +1 -1
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/mcp/workspace-tools.d.ts +7 -4
- package/dist/cli/mcp/workspace-tools.d.ts.map +1 -1
- package/dist/cli/plugins.d.ts.map +1 -1
- package/dist/cli/registry.d.ts +42 -1
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/codegen/pinned-upgrade.d.ts.map +1 -1
- package/dist/components/verbs/vuln-scan.d.ts +72 -0
- package/dist/components/verbs/vuln-scan.d.ts.map +1 -1
- package/dist/config.d.ts +22 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/lexicon-module.d.ts +22 -0
- package/dist/lexicon-module.d.ts.map +1 -1
- package/dist/lifecycle/converge-ledger.d.ts +19 -0
- package/dist/lifecycle/converge-ledger.d.ts.map +1 -1
- package/dist/lifecycle/git.d.ts +40 -5
- package/dist/lifecycle/git.d.ts.map +1 -1
- package/dist/lifecycle/lease.d.ts +72 -16
- package/dist/lifecycle/lease.d.ts.map +1 -1
- package/dist/lifecycle/member-ledger.d.ts +3 -2
- package/dist/lifecycle/member-ledger.d.ts.map +1 -1
- package/dist/lifecycle/plan-ledger.d.ts +114 -0
- package/dist/lifecycle/plan-ledger.d.ts.map +1 -0
- package/dist/lifecycle/run-ledger.d.ts +2 -0
- package/dist/lifecycle/run-ledger.d.ts.map +1 -1
- package/dist/lifecycle/symptoms.d.ts +51 -0
- package/dist/lifecycle/symptoms.d.ts.map +1 -1
- package/dist/lifecycle/work-lease.d.ts +140 -0
- package/dist/lifecycle/work-lease.d.ts.map +1 -0
- package/dist/lint/rules/index.d.ts +4 -2
- package/dist/lint/rules/index.d.ts.map +1 -1
- package/dist/lint/rules/op/index.d.ts +14 -3
- package/dist/lint/rules/op/index.d.ts.map +1 -1
- package/dist/lint/rules/op/ops014-converge-rule-refusals.d.ts.map +1 -1
- package/dist/lint/rules/op/sys010-key-over-plain-http.d.ts +29 -0
- package/dist/lint/rules/op/sys010-key-over-plain-http.d.ts.map +1 -0
- package/dist/lint/rules/sys001-no-literal-key.d.ts +3 -0
- package/dist/lint/rules/sys001-no-literal-key.d.ts.map +1 -0
- package/dist/op/__fixtures__/decide-stub-backend.d.ts +53 -0
- package/dist/op/__fixtures__/decide-stub-backend.d.ts.map +1 -0
- package/dist/op/activities/activity-contracts.d.ts +203 -2
- package/dist/op/activities/activity-contracts.d.ts.map +1 -1
- package/dist/op/activities/apply.d.ts.map +1 -1
- package/dist/op/activities/change-coverage.d.ts +44 -0
- package/dist/op/activities/change-coverage.d.ts.map +1 -0
- package/dist/op/activities/converge.d.ts +24 -1
- package/dist/op/activities/converge.d.ts.map +1 -1
- package/dist/op/activities/decide.d.ts +107 -0
- package/dist/op/activities/decide.d.ts.map +1 -0
- package/dist/op/activities/index.d.ts +10 -0
- package/dist/op/activities/index.d.ts.map +1 -1
- package/dist/op/activities/shell.d.ts +32 -0
- package/dist/op/activities/shell.d.ts.map +1 -1
- package/dist/op/activities/source-release.d.ts +86 -0
- package/dist/op/activities/source-release.d.ts.map +1 -0
- package/dist/op/activities/source-rollback.d.ts +100 -0
- package/dist/op/activities/source-rollback.d.ts.map +1 -0
- package/dist/op/activities/work-evidence.d.ts +42 -0
- package/dist/op/activities/work-evidence.d.ts.map +1 -0
- package/dist/op/activity-contract.d.ts +1 -0
- package/dist/op/activity-contract.d.ts.map +1 -1
- package/dist/op/activity-profiles.d.ts +16 -0
- package/dist/op/activity-profiles.d.ts.map +1 -1
- package/dist/op/builders.d.ts +84 -2
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/composites/converge-op.d.ts +31 -4
- package/dist/op/composites/converge-op.d.ts.map +1 -1
- package/dist/op/decide-backend.d.ts +116 -0
- package/dist/op/decide-backend.d.ts.map +1 -0
- package/dist/op/decide-config.d.ts +120 -0
- package/dist/op/decide-config.d.ts.map +1 -0
- package/dist/op/decide-read-inputs.d.ts +40 -0
- package/dist/op/decide-read-inputs.d.ts.map +1 -0
- package/dist/op/discover.d.ts +25 -0
- package/dist/op/discover.d.ts.map +1 -1
- package/dist/op/gate-wait.d.ts +43 -0
- package/dist/op/gate-wait.d.ts.map +1 -0
- package/dist/op/gate.d.ts +5 -2
- package/dist/op/gate.d.ts.map +1 -1
- package/dist/op/index.d.ts +18 -5
- package/dist/op/index.d.ts.map +1 -1
- package/dist/op/lifecycle-receipt-store.d.ts +34 -0
- package/dist/op/lifecycle-receipt-store.d.ts.map +1 -0
- package/dist/op/local-executor.d.ts +48 -4
- package/dist/op/local-executor.d.ts.map +1 -1
- package/dist/op/local-output.d.ts +2 -0
- package/dist/op/local-output.d.ts.map +1 -1
- package/dist/op/op-ir.d.ts +12 -1
- package/dist/op/op-ir.d.ts.map +1 -1
- package/dist/op/op-verb-class.d.ts.map +1 -1
- package/dist/op/operator.d.ts +126 -1
- package/dist/op/operator.d.ts.map +1 -1
- package/dist/op/runtime.d.ts +46 -5
- package/dist/op/runtime.d.ts.map +1 -1
- package/dist/op/runtimes/local.d.ts.map +1 -1
- package/dist/op/source-archive.d.ts +63 -0
- package/dist/op/source-archive.d.ts.map +1 -0
- package/dist/op/step-output-ref.d.ts +2 -2
- package/dist/op/step-output-ref.d.ts.map +1 -1
- package/dist/op/steward-points.d.ts +136 -0
- package/dist/op/steward-points.d.ts.map +1 -0
- package/dist/op/steward-turn.d.ts +53 -0
- package/dist/op/steward-turn.d.ts.map +1 -0
- package/dist/op/steward.d.ts +161 -0
- package/dist/op/steward.d.ts.map +1 -0
- package/dist/op/types.d.ts +58 -0
- package/dist/op/types.d.ts.map +1 -1
- package/dist/op/work-lease-decl.d.ts +18 -0
- package/dist/op/work-lease-decl.d.ts.map +1 -0
- package/dist/op/work-lease-run.d.ts +173 -0
- package/dist/op/work-lease-run.d.ts.map +1 -0
- package/dist/workspace/__fixtures__/decide-workspace.d.ts +100 -0
- package/dist/workspace/__fixtures__/decide-workspace.d.ts.map +1 -0
- package/dist/workspace/answers-ledger.d.ts +76 -0
- package/dist/workspace/answers-ledger.d.ts.map +1 -0
- package/dist/workspace/box-isolation.d.ts +99 -0
- package/dist/workspace/box-isolation.d.ts.map +1 -0
- package/dist/workspace/changes-cli.d.ts +16 -0
- package/dist/workspace/changes-cli.d.ts.map +1 -0
- package/dist/workspace/changes.d.ts +200 -0
- package/dist/workspace/changes.d.ts.map +1 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-fly-site.d.ts +59 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-fly-site.d.ts.map +1 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-live-names.d.ts +51 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-live-names.d.ts.map +1 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-rollback.d.ts +26 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-rollback.d.ts.map +1 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-ship-inputs.d.ts +59 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-ship-inputs.d.ts.map +1 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-ship-policy.d.ts +22 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-ship-policy.d.ts.map +1 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit.d.ts +71 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit.d.ts.map +1 -0
- package/dist/workspace/chant-migrations.d.ts +99 -0
- package/dist/workspace/chant-migrations.d.ts.map +1 -0
- package/dist/workspace/checks/box-isolation.d.ts +18 -0
- package/dist/workspace/checks/box-isolation.d.ts.map +1 -0
- package/dist/workspace/checks/boxes.d.ts +104 -0
- package/dist/workspace/checks/boxes.d.ts.map +1 -0
- package/dist/workspace/checks/diagrams.d.ts +31 -0
- package/dist/workspace/checks/diagrams.d.ts.map +1 -0
- package/dist/workspace/checks/records.d.ts +8 -0
- package/dist/workspace/checks/records.d.ts.map +1 -1
- package/dist/workspace/checks.d.ts +13 -1
- package/dist/workspace/checks.d.ts.map +1 -1
- package/dist/workspace/compose-graph.d.ts +2 -0
- package/dist/workspace/compose-graph.d.ts.map +1 -1
- package/dist/workspace/conformance/index.d.ts.map +1 -1
- package/dist/workspace/decide.d.ts +229 -0
- package/dist/workspace/decide.d.ts.map +1 -0
- package/dist/workspace/decision-points.schema.json +137 -0
- package/dist/workspace/declaration.d.ts +103 -0
- package/dist/workspace/declaration.d.ts.map +1 -1
- package/dist/workspace/declaration.schema.json +285 -0
- package/dist/workspace/declared-kinds.d.ts +32 -0
- package/dist/workspace/declared-kinds.d.ts.map +1 -1
- package/dist/workspace/generated-files.d.ts +7 -0
- package/dist/workspace/generated-files.d.ts.map +1 -1
- package/dist/workspace/intent.d.ts.map +1 -1
- package/dist/workspace/lineage-check.d.ts +3 -0
- package/dist/workspace/lineage-check.d.ts.map +1 -1
- package/dist/workspace/lineage-upgrade.d.ts +6 -1
- package/dist/workspace/lineage-upgrade.d.ts.map +1 -1
- package/dist/workspace/ls.d.ts +39 -1
- package/dist/workspace/ls.d.ts.map +1 -1
- package/dist/workspace/point-answer.schema.json +95 -0
- package/dist/workspace/points-cli.d.ts +113 -0
- package/dist/workspace/points-cli.d.ts.map +1 -0
- package/dist/workspace/points.d.ts +320 -0
- package/dist/workspace/points.d.ts.map +1 -0
- package/dist/workspace/reason-codes.d.ts +38 -0
- package/dist/workspace/reason-codes.d.ts.map +1 -1
- package/dist/workspace/record-assets.d.ts.map +1 -1
- package/dist/workspace/records-cli.d.ts +23 -1
- package/dist/workspace/records-cli.d.ts.map +1 -1
- package/dist/workspace/records-close.d.ts +1 -1
- package/dist/workspace/records-close.d.ts.map +1 -1
- package/dist/workspace/records-write.d.ts +11 -5
- package/dist/workspace/records-write.d.ts.map +1 -1
- package/dist/workspace/records.d.ts +42 -6
- package/dist/workspace/records.d.ts.map +1 -1
- package/dist/workspace/status-gates.d.ts +7 -2
- package/dist/workspace/status-gates.d.ts.map +1 -1
- package/dist/workspace/status-stewards.d.ts +179 -0
- package/dist/workspace/status-stewards.d.ts.map +1 -0
- package/dist/workspace/status.d.ts +68 -1
- package/dist/workspace/status.d.ts.map +1 -1
- package/dist/workspace/work-cli.d.ts +189 -0
- package/dist/workspace/work-cli.d.ts.map +1 -0
- package/dist/workspace/work-evidence.d.ts +74 -0
- package/dist/workspace/work-evidence.d.ts.map +1 -0
- package/dist/workspace/work.d.ts +43 -1
- package/dist/workspace/work.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/cli/commands/audit.test.ts +9 -1
- package/src/cli/commands/build.ts +3 -2
- package/src/cli/commands/lint.ts +7 -1
- package/src/cli/handlers/components.test.ts +93 -0
- package/src/cli/handlers/components.ts +44 -3
- package/src/cli/handlers/graph.test.ts +20 -0
- package/src/cli/handlers/graph.ts +16 -2
- package/src/cli/handlers/operator.ts +141 -4
- package/src/cli/handlers/run.test.ts +173 -2
- package/src/cli/handlers/run.ts +174 -3
- package/src/cli/main.test.ts +50 -0
- package/src/cli/main.ts +97 -2
- package/src/cli/mcp/workspace-tools.test.ts +48 -19
- package/src/cli/mcp/workspace-tools.ts +110 -8
- package/src/cli/plugins.ts +11 -3
- package/src/cli/registry.ts +42 -1
- package/src/codegen/pinned-upgrade.ts +2 -1
- package/src/codegen/release-wiring.test.ts +49 -2
- package/src/components/capability-plugin-loader.ts +3 -3
- package/src/components/cli-support.ts +2 -2
- package/src/components/verbs/vuln-scan.test.ts +124 -1
- package/src/components/verbs/vuln-scan.ts +142 -1
- package/src/config.ts +11 -0
- package/src/lexicon-module.ts +56 -1
- package/src/lexicon-package.test.ts +96 -0
- package/src/lifecycle/converge-ledger.ts +20 -0
- package/src/lifecycle/git.ts +65 -15
- package/src/lifecycle/lease.test.ts +22 -0
- package/src/lifecycle/lease.ts +133 -29
- package/src/lifecycle/member-ledger.ts +3 -2
- package/src/lifecycle/plan-ledger.test.ts +148 -0
- package/src/lifecycle/plan-ledger.ts +158 -0
- package/src/lifecycle/run-ledger.ts +6 -0
- package/src/lifecycle/symptoms.ts +95 -0
- package/src/lifecycle/work-lease.test.ts +236 -0
- package/src/lifecycle/work-lease.ts +426 -0
- package/src/lint/rules/index.ts +6 -2
- package/src/lint/rules/op/index.ts +17 -4
- package/src/lint/rules/op/ops014-converge-rule-refusals.test.ts +23 -1
- package/src/lint/rules/op/ops014-converge-rule-refusals.ts +10 -6
- package/src/lint/rules/op/sys010-key-over-plain-http.test.ts +52 -0
- package/src/lint/rules/op/sys010-key-over-plain-http.ts +100 -0
- package/src/lint/rules/sys001-no-literal-key.test.ts +31 -0
- package/src/lint/rules/sys001-no-literal-key.ts +67 -0
- package/src/op/__fixtures__/decide-stub-backend.ts +143 -0
- package/src/op/activities/activity-contracts.ts +190 -1
- package/src/op/activities/apply.ts +7 -6
- package/src/op/activities/change-coverage.ts +60 -0
- package/src/op/activities/converge.test.ts +55 -1
- package/src/op/activities/converge.ts +208 -29
- package/src/op/activities/decide.live.test.ts +78 -0
- package/src/op/activities/decide.test.ts +300 -0
- package/src/op/activities/decide.ts +267 -0
- package/src/op/activities/index.ts +21 -0
- package/src/op/activities/shell.test.ts +91 -1
- package/src/op/activities/shell.ts +91 -2
- package/src/op/activities/source-release.test.ts +118 -0
- package/src/op/activities/source-release.ts +168 -0
- package/src/op/activities/source-rollback.test.ts +131 -0
- package/src/op/activities/source-rollback.ts +239 -0
- package/src/op/activities/work-evidence.ts +62 -0
- package/src/op/activity-contract-registry.test.ts +2 -0
- package/src/op/activity-contract-registry.ts +2 -2
- package/src/op/activity-contract.test.ts +12 -0
- package/src/op/activity-contract.ts +6 -1
- package/src/op/activity-profiles.ts +29 -0
- package/src/op/activity-registry.test.ts +1 -1
- package/src/op/activity-registry.ts +2 -2
- package/src/op/builders.ts +124 -5
- package/src/op/command-gate.test.ts +192 -0
- package/src/op/composites/converge-op.test.ts +27 -1
- package/src/op/composites/converge-op.ts +69 -15
- package/src/op/decide-backend.test.ts +44 -0
- package/src/op/decide-backend.ts +212 -0
- package/src/op/decide-config.test.ts +52 -0
- package/src/op/decide-config.ts +80 -0
- package/src/op/decide-read-inputs.ts +117 -0
- package/src/op/discover.ts +71 -0
- package/src/op/gate-approval.ts +2 -2
- package/src/op/gate-wait.ts +57 -0
- package/src/op/gate.ts +8 -3
- package/src/op/generate-pipeline.ts +2 -2
- package/src/op/index.ts +34 -6
- package/src/op/lifecycle-receipt-store.test.ts +60 -0
- package/src/op/lifecycle-receipt-store.ts +61 -0
- package/src/op/local-executor.ts +367 -33
- package/src/op/local-output.test.ts +33 -0
- package/src/op/local-output.ts +33 -2
- package/src/op/op-ir.test.ts +10 -0
- package/src/op/op-ir.ts +18 -0
- package/src/op/op-verb-class.ts +1 -0
- package/src/op/operator.ts +360 -10
- package/src/op/runtime.ts +37 -8
- package/src/op/runtimes/local.ts +6 -1
- package/src/op/source-archive.ts +161 -0
- package/src/op/step-output-ref.ts +6 -2
- package/src/op/steward-points.test.ts +313 -0
- package/src/op/steward-points.ts +194 -0
- package/src/op/steward-turn.ts +79 -0
- package/src/op/steward.test.ts +296 -0
- package/src/op/steward.ts +277 -0
- package/src/op/types.ts +60 -0
- package/src/op/work-lease-decl.ts +80 -0
- package/src/op/work-lease-run.test.ts +345 -0
- package/src/op/work-lease-run.ts +395 -0
- package/src/workspace/__fixtures__/decide-workspace.ts +129 -0
- package/src/workspace/__fixtures__/studio-template-84c8b21.json +67 -0
- package/src/workspace/answers-ledger.ts +118 -0
- package/src/workspace/box-isolation.test.ts +261 -0
- package/src/workspace/box-isolation.ts +205 -0
- package/src/workspace/changes-cli.ts +56 -0
- package/src/workspace/changes.schema.json +472 -0
- package/src/workspace/changes.test.ts +315 -0
- package/src/workspace/changes.ts +512 -0
- package/src/workspace/chant-migrations/chud-lexicon-exit-fly-site.ts +234 -0
- package/src/workspace/chant-migrations/chud-lexicon-exit-live-names.ts +164 -0
- package/src/workspace/chant-migrations/chud-lexicon-exit-rollback.ts +223 -0
- package/src/workspace/chant-migrations/chud-lexicon-exit-ship-inputs.ts +195 -0
- package/src/workspace/chant-migrations/chud-lexicon-exit-ship-policy.ts +108 -0
- package/src/workspace/chant-migrations/chud-lexicon-exit.ts +882 -0
- package/src/workspace/chant-migrations.e2e.test.ts +1089 -0
- package/src/workspace/chant-migrations.ts +164 -0
- package/src/workspace/check-contract.test.ts +5 -1
- package/src/workspace/check.schema.json +25 -7
- package/src/workspace/checks/box-isolation.ts +68 -0
- package/src/workspace/checks/boxes.test.ts +276 -0
- package/src/workspace/checks/boxes.ts +442 -0
- package/src/workspace/checks/diagrams.test.ts +134 -0
- package/src/workspace/checks/diagrams.ts +108 -0
- package/src/workspace/checks/records.ts +72 -0
- package/src/workspace/checks.test.ts +7 -0
- package/src/workspace/checks.ts +27 -3
- package/src/workspace/compose-graph.ts +2 -0
- package/src/workspace/conformance/__fixture__/decisions/decision.kind.mjs +10 -0
- package/src/workspace/conformance/__fixture__/decisions/decision.schema.json +26 -0
- package/src/workspace/conformance/index.ts +5 -0
- package/src/workspace/decide.test.ts +224 -0
- package/src/workspace/decide.ts +709 -0
- package/src/workspace/decision-points.schema.json +137 -0
- package/src/workspace/declaration.schema.json +285 -0
- package/src/workspace/declaration.test.ts +58 -0
- package/src/workspace/declaration.ts +241 -0
- package/src/workspace/declared-kinds.test.ts +5 -5
- package/src/workspace/declared-kinds.ts +71 -3
- package/src/workspace/generated-files.ts +14 -0
- package/src/workspace/graph-cli.ts +1 -1
- package/src/workspace/graph.schema.json +9 -1
- package/src/workspace/intent.schema.json +12 -3
- package/src/workspace/intent.ts +3 -10
- package/src/workspace/lineage-check.ts +16 -1
- package/src/workspace/lineage-upgrade-cli.ts +1 -1
- package/src/workspace/lineage-upgrade.test.ts +70 -0
- package/src/workspace/lineage-upgrade.ts +81 -10
- package/src/workspace/ls-contract.test.ts +57 -0
- package/src/workspace/ls.schema.json +46 -1
- package/src/workspace/ls.ts +62 -3
- package/src/workspace/point-answer.schema.json +95 -0
- package/src/workspace/points-cli.ts +284 -0
- package/src/workspace/points-write.schema.json +499 -0
- package/src/workspace/points.schema.json +743 -0
- package/src/workspace/points.test.ts +264 -0
- package/src/workspace/points.ts +564 -0
- package/src/workspace/read-contract.test.ts +18 -1
- package/src/workspace/reason-codes.test.ts +24 -1
- package/src/workspace/reason-codes.ts +49 -0
- package/src/workspace/record-assets.test.ts +3 -2
- package/src/workspace/record-assets.ts +4 -1
- package/src/workspace/records-amend.schema.json +2 -0
- package/src/workspace/records-cli.ts +28 -5
- package/src/workspace/records-close.schema.json +2 -0
- package/src/workspace/records-contract.test.ts +3 -2
- package/src/workspace/records-new.schema.json +2 -0
- package/src/workspace/records-review.schema.json +2 -0
- package/src/workspace/records-sessions-write.e2e.test.ts +77 -0
- package/src/workspace/records-sessions-write.test.ts +2 -34
- package/src/workspace/records-write.e2e.test.ts +108 -0
- package/src/workspace/records-write.test.ts +32 -41
- package/src/workspace/records-write.ts +33 -15
- package/src/workspace/records.schema.json +53 -2
- package/src/workspace/records.test.ts +48 -3
- package/src/workspace/records.ts +142 -6
- package/src/workspace/status-contract.test.ts +189 -6
- package/src/workspace/status-gates.ts +9 -4
- package/src/workspace/status-stewards.ts +329 -0
- package/src/workspace/status.schema.json +335 -5
- package/src/workspace/status.ts +142 -6
- package/src/workspace/work-acceptance.test.ts +274 -0
- package/src/workspace/work-cli.e2e.test.ts +180 -0
- package/src/workspace/work-cli.ts +429 -0
- package/src/workspace/work-evidence.schema.json +212 -0
- package/src/workspace/work-evidence.ts +169 -0
- package/src/workspace/work-history.schema.json +349 -0
- package/src/workspace/work-history.test.ts +156 -0
- package/src/workspace/work-lease.schema.json +233 -0
- package/src/workspace/work-readiness-chud.test.ts +145 -0
- package/src/workspace/work.test.ts +3 -2
- package/src/workspace/work.ts +100 -1
- /package/src/cli/{discovery-skip.test.ts → discovery-skip.e2e.test.ts} +0 -0
- /package/src/workspace/conformance/{conformance.test.ts → conformance.e2e.test.ts} +0 -0
- /package/src/workspace/{which-chant.test.ts → which-chant.e2e.test.ts} +0 -0
package/src/cli/main.ts
CHANGED
|
@@ -54,6 +54,7 @@ import type { LexiconPlugin } from "../lexicon";
|
|
|
54
54
|
*/
|
|
55
55
|
const BOOLEAN_FLAGS = new Set([
|
|
56
56
|
"--help",
|
|
57
|
+
"--open",
|
|
57
58
|
"--version",
|
|
58
59
|
"--agents",
|
|
59
60
|
"--agent",
|
|
@@ -378,6 +379,14 @@ export function parseArgs(args: string[]): ParsedArgs {
|
|
|
378
379
|
// `chant workspace graph --intent <path[:start-end]>` (#2651)
|
|
379
380
|
result.intent = args[++i];
|
|
380
381
|
if (!result.intent || result.intent.startsWith("-")) throw new Error("--intent needs a region: --intent <path[:start-end]>");
|
|
382
|
+
} else if (arg === "--changes") {
|
|
383
|
+
// `chant workspace check --changes <base>..<head>` (#2773)
|
|
384
|
+
result.changes = args[++i];
|
|
385
|
+
if (!result.changes || result.changes.startsWith("-")) throw new Error("--changes needs a range: --changes <base>..<head>");
|
|
386
|
+
} else if (arg === "--severity") {
|
|
387
|
+
// `chant workspace check --changes <range> --severity off|warn|fail` (#2773)
|
|
388
|
+
result.severity = args[++i];
|
|
389
|
+
if (!result.severity || result.severity.startsWith("-")) throw new Error("--severity needs off, warn or fail");
|
|
381
390
|
} else if (arg === "--current") {
|
|
382
391
|
result.current = true;
|
|
383
392
|
} else if (arg === "--set") {
|
|
@@ -392,6 +401,27 @@ export function parseArgs(args: string[]): ParsedArgs {
|
|
|
392
401
|
// `chant workspace records review <id> --by <principal>` (#2670): whoever the caller says.
|
|
393
402
|
result.by = args[++i];
|
|
394
403
|
if (!result.by || result.by.startsWith("-")) throw new Error("--by needs the reviewer: --by <principal>");
|
|
404
|
+
// Repeatable for `workspace points answer` (#2739): each person who answered.
|
|
405
|
+
(result.bys ??= []).push(result.by);
|
|
406
|
+
} else if (arg === "--open") {
|
|
407
|
+
// `chant workspace points --open` (#2739): only the questions still open.
|
|
408
|
+
result.open = true;
|
|
409
|
+
} else if (arg === "--inputs") {
|
|
410
|
+
// `chant workspace points ask <point> --inputs <file|->` (#2739)
|
|
411
|
+
result.inputs = args[++i];
|
|
412
|
+
if (!result.inputs || (result.inputs.startsWith("-") && result.inputs !== "-")) throw new Error("--inputs needs a JSON file, or - for standard input: --inputs <file|->");
|
|
413
|
+
} else if (arg === "--response") {
|
|
414
|
+
// `chant workspace points ask <point> --response <file>` (#2739): a POST /v1/systemone response the caller got.
|
|
415
|
+
result.response = args[++i];
|
|
416
|
+
if (!result.response || result.response.startsWith("-")) throw new Error("--response needs a JSON file: --response <file>");
|
|
417
|
+
} else if (arg === "--subject") {
|
|
418
|
+
// `chant workspace points ask <point> --subject <id>` (#2739): what the question is about.
|
|
419
|
+
result.subject = args[++i];
|
|
420
|
+
if (!result.subject || result.subject.startsWith("-")) throw new Error("--subject needs what the question is about, such as a work item id: --subject <id>");
|
|
421
|
+
} else if (arg === "--answer") {
|
|
422
|
+
// `chant workspace points answer <id> --answer <value>` (#2739)
|
|
423
|
+
result.answer = args[++i];
|
|
424
|
+
if (result.answer === undefined || result.answer === "") throw new Error("--answer needs one of the question's candidates: --answer <value>");
|
|
395
425
|
} else if (arg === "--sign") {
|
|
396
426
|
// `chant workspace records review <id> --sign [<key file>]` (#2687): seal the verdict.
|
|
397
427
|
// `records new` and `records amend` take it too, to seal the record's author (#2688).
|
|
@@ -431,6 +461,8 @@ export function parseArgs(args: string[]): ParsedArgs {
|
|
|
431
461
|
} else if (arg === "--digest") {
|
|
432
462
|
result.digest = args[++i];
|
|
433
463
|
if (result.digest !== undefined) (result.digests ??= []).push(result.digest);
|
|
464
|
+
} else if (arg === "--release-plan") {
|
|
465
|
+
result.releasePlanFile = args[++i];
|
|
434
466
|
} else if (arg === "--git-sha") {
|
|
435
467
|
result.gitSha = args[++i];
|
|
436
468
|
} else if (arg === "--run-id") {
|
|
@@ -483,8 +515,28 @@ export function parseArgs(args: string[]): ParsedArgs {
|
|
|
483
515
|
result.interval = args[++i];
|
|
484
516
|
} else if (arg === "--lease-ttl") {
|
|
485
517
|
result.leaseTtl = args[++i];
|
|
518
|
+
} else if (arg === "--steward") {
|
|
519
|
+
// #2731 — the name is optional: a project with one steward runs it
|
|
520
|
+
// with a bare `--steward`.
|
|
521
|
+
const next = args[i + 1];
|
|
522
|
+
if (next !== undefined && !next.startsWith("-")) {
|
|
523
|
+
result.steward = next;
|
|
524
|
+
i++;
|
|
525
|
+
} else {
|
|
526
|
+
result.steward = "";
|
|
527
|
+
}
|
|
486
528
|
} else if (arg === "--once") {
|
|
487
529
|
result.once = true;
|
|
530
|
+
} else if (arg === "--work") {
|
|
531
|
+
// `chant run <op> --work <id>` (#2748)
|
|
532
|
+
const value = args[++i];
|
|
533
|
+
if (!value || value.startsWith("-")) throw new Error("--work needs a work item id: --work <id>");
|
|
534
|
+
result.work = value;
|
|
535
|
+
} else if (arg === "--holder" || arg === "--ttl" || arg === "--token" || arg === "--outcome") {
|
|
536
|
+
// `chant workspace work claim|renew|release <id>` (#2732)
|
|
537
|
+
const value = args[++i];
|
|
538
|
+
if (!value || value.startsWith("-")) throw new Error(`${arg} needs a value: ${arg} <${arg.slice(2)}>`);
|
|
539
|
+
result[arg.slice(2) as "holder" | "ttl" | "token" | "outcome"] = value;
|
|
488
540
|
} else if (arg === "--note") {
|
|
489
541
|
result.note = args[++i];
|
|
490
542
|
} else if (arg === "--expire") {
|
|
@@ -664,6 +716,8 @@ Commands:
|
|
|
664
716
|
|
|
665
717
|
Ops:
|
|
666
718
|
run <name> Run an Op on the resolved runtime (--on; local by default)
|
|
719
|
+
[--work <id>] [--holder <name>]: the work item an Op
|
|
720
|
+
with a work lease runs under, and who holds it
|
|
667
721
|
run list List all Ops with the runtime's state for each
|
|
668
722
|
run status <name> Show the runtime's state for one Op's latest run
|
|
669
723
|
run approve <op> <gate> Record a gate's resolution and wake the runtime
|
|
@@ -691,7 +745,10 @@ Ops:
|
|
|
691
745
|
environment; --interval <dur> (default 60s) and
|
|
692
746
|
--lease-ttl <dur> (default 5m) tune cadence; --once
|
|
693
747
|
runs a single round and exits (cron/systemd-timer/
|
|
694
|
-
CronJob invokers use this instead of the daemon)
|
|
748
|
+
CronJob invokers use this instead of the daemon).
|
|
749
|
+
--steward [<name>] runs a declared steward's local
|
|
750
|
+
form instead (#2731): its scheduled Ops on their
|
|
751
|
+
crons, under the steward's own lease
|
|
695
752
|
operator status Last tick, outcomes, and pending gates per
|
|
696
753
|
ConvergeOp, read from the chant/lifecycle orphan
|
|
697
754
|
branch alone — no daemon needs to be running
|
|
@@ -802,6 +859,29 @@ Workspace (level 1, #2524):
|
|
|
802
859
|
closing commit and seal, in one write. Without
|
|
803
860
|
--kind, the one session kind the declaration names.
|
|
804
861
|
Prints {path, id, changed, seal, closedRev}
|
|
862
|
+
workspace work claim|renew|release <id> --holder <name> [--kind <kind file>] [--ttl <seconds|duration>] [--token <token>] [--outcome <text>] [--note <text>] [--json]
|
|
863
|
+
Take, heartbeat or give back the lease on a work item:
|
|
864
|
+
refs/chant/lease/work/<id>, a compare-and-set ref with a
|
|
865
|
+
fencing token and an expiry, pushed to the remote so
|
|
866
|
+
separate clones coordinate. A claim is refused, exit 2,
|
|
867
|
+
while anyone holds it live. Each change appends to
|
|
868
|
+
_leases/<id>.jsonl on chant/lifecycle
|
|
869
|
+
workspace work history <id> [--kind <kind file>] [--json]
|
|
870
|
+
A work item's lease history: each claim with its token
|
|
871
|
+
and holder, and how it ended, released with an outcome
|
|
872
|
+
or never released (expired or lost). Read-only
|
|
873
|
+
workspace points [--open] [--kind <kind file>] [--at <rev>] [--json]
|
|
874
|
+
List the decision points the declared answer kinds'
|
|
875
|
+
points files declare, and the questions asked of them;
|
|
876
|
+
--open keeps the escalated and proposed ones (ws-058)
|
|
877
|
+
workspace points ask <point> --inputs <file|-> [--response <file>] [--subject <id>] [--kind <kind file>] [--dry-run]
|
|
878
|
+
Ask a point's table, model and quorum deciders and
|
|
879
|
+
record the answer: proposed from a model, escalated to
|
|
880
|
+
people below its threshold. --response is a POST
|
|
881
|
+
/v1/systemone response the caller got; chant calls no model
|
|
882
|
+
workspace points answer <id> --answer <value> --by <name>... [--kind <kind file>] [--dry-run]
|
|
883
|
+
Record people's answer to an open question, or confirm
|
|
884
|
+
a model's proposal, once the point's quorum is met
|
|
805
885
|
workspace verify [--base <rev>] [--head <rev>] [--require attested]
|
|
806
886
|
Check the commits in base..head against the signers
|
|
807
887
|
and roles read from base. A change to the signers file
|
|
@@ -828,6 +908,13 @@ Workspace (level 1, #2524):
|
|
|
828
908
|
whose pinned files changed. Needs no workspace file.
|
|
829
909
|
--at reads a commit's git objects; --format json
|
|
830
910
|
prints the read-contract document
|
|
911
|
+
workspace check --changes <base>..<head> [--work <id>] [--severity off|warn|fail] [--kind <kind file>...] [--json]
|
|
912
|
+
Map each path the diff changes to the current records
|
|
913
|
+
whose constrains cover it: change-uncovered when none
|
|
914
|
+
does, change-out-of-scope when a record in hand (the
|
|
915
|
+
--work item and its decisions) lists it in
|
|
916
|
+
out_of_scope. The declaration's changes block sets
|
|
917
|
+
the severity (warn by default) and ignore globs
|
|
831
918
|
workspace build [dir] [--member <name>] [-o <dir>] [--dry-run]
|
|
832
919
|
Build every chant member and example project, each with
|
|
833
920
|
its own chant, one process per toolchain. -o <dir>
|
|
@@ -904,7 +991,11 @@ Component release ledger + status:
|
|
|
904
991
|
<file> finishes an attempt that stopped)
|
|
905
992
|
components release <env> Append one immutable release record
|
|
906
993
|
(--component <name> --digest <sha256:...>
|
|
907
|
-
[--git-sha <sha>] [--run-id <id>] [--actor <name>])
|
|
994
|
+
[--git-sha <sha>] [--run-id <id>] [--actor <name>]);
|
|
995
|
+
--release-plan <file> takes --digest's place,
|
|
996
|
+
persisting the release plan the file holds to
|
|
997
|
+
_plans/<digest>.json (ws-055) and recording its
|
|
998
|
+
own digest
|
|
908
999
|
components export <env> Materialize a persisted build archive manifest to
|
|
909
1000
|
a portable directory (--component <name>
|
|
910
1001
|
[--digest <manifestDigest>] -o <dir> [--json]);
|
|
@@ -1328,8 +1419,12 @@ export const commandRegistry: CommandDef[] = [
|
|
|
1328
1419
|
// Workspace reads (#2524). Imported on first use, so a level-0 command never
|
|
1329
1420
|
// loads anything under workspace/ (#2525 rule 5, pinned by #2526's goldens).
|
|
1330
1421
|
{ name: "workspace records", handler: async (ctx) => (await import("../workspace/records-cli")).runWorkspaceRecords(ctx) },
|
|
1422
|
+
// ws-058 (#2739) — decision points and the questions asked of them; never calls a model.
|
|
1423
|
+
{ name: "workspace points", handler: async (ctx) => (await import("../workspace/points-cli")).runWorkspacePoints(ctx) },
|
|
1331
1424
|
{ name: "workspace init", handler: async (ctx) => (await import("../workspace/init")).runWorkspaceInit(ctx) },
|
|
1332
1425
|
{ name: "workspace ls", handler: async (ctx) => (await import("../workspace/ls")).runWorkspaceLs(ctx) },
|
|
1426
|
+
// #2732 — the work lease: claim, renew and release a work item.
|
|
1427
|
+
{ name: "workspace work", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/work-cli")).runWorkspaceWork(ctx) },
|
|
1333
1428
|
{ name: "workspace status", handler: async (ctx) => (await import("../workspace/status")).runWorkspaceStatus(ctx) },
|
|
1334
1429
|
{ name: "workspace lineage", handler: async (ctx) => (await import("../workspace/lineage-cli")).runWorkspaceLineage(ctx) },
|
|
1335
1430
|
{ name: "workspace upgrade", handler: async (ctx) => (await import("../workspace/lineage-upgrade-cli")).runWorkspaceUpgrade(ctx) },
|
|
@@ -85,7 +85,7 @@ describe("which servers have the workspace tools", () => {
|
|
|
85
85
|
const { tools } = (await rpc(server(cwd), "tools/list")) as { tools: { name: string }[] };
|
|
86
86
|
expect(tools.map((t) => t.name)).toEqual(expect.arrayContaining(names));
|
|
87
87
|
}
|
|
88
|
-
expect(names).toEqual(["workspace-ls", "workspace-status", "workspace-graph", "workspace-records", "records-new", "records-amend", "records-review", "records-close"]);
|
|
88
|
+
expect(names).toEqual(["workspace-ls", "workspace-status", "workspace-graph", "workspace-changes", "workspace-records", "workspace-points", "workspace-work-history", "records-new", "records-amend", "records-review", "records-close", "points-answer"]);
|
|
89
89
|
});
|
|
90
90
|
|
|
91
91
|
test("a server outside any workspace, or given none, does not", async () => {
|
|
@@ -100,8 +100,8 @@ describe("which servers have the workspace tools", () => {
|
|
|
100
100
|
}
|
|
101
101
|
});
|
|
102
102
|
|
|
103
|
-
test("the descriptions say records are proposals and by names who decided", () => {
|
|
104
|
-
for (const t of workspaceWriteTools) expect(t.description).toMatch(/proposals until they are reviewed.*by must name the person or agent that actually decided/s);
|
|
103
|
+
test("the descriptions say records are proposals and by names who proposed or decided", () => {
|
|
104
|
+
for (const t of workspaceWriteTools) expect(t.description).toMatch(/proposals until they are reviewed.*by must name the person or agent that actually proposed or decided it/s);
|
|
105
105
|
});
|
|
106
106
|
});
|
|
107
107
|
|
|
@@ -115,6 +115,41 @@ describe("reads", () => {
|
|
|
115
115
|
expect(recordsOf(only.structuredContent).map((r) => r.id)).toEqual(["fix-001"]);
|
|
116
116
|
}, 120_000);
|
|
117
117
|
|
|
118
|
+
test("workspace-points returns the document chant workspace points --json prints, and points-answer the write's (ws-058)", async () => {
|
|
119
|
+
const s = server();
|
|
120
|
+
const res = await call(s, "workspace-points", { open: true });
|
|
121
|
+
expect(res.isError).toBeUndefined();
|
|
122
|
+
expect(res.structuredContent).toEqual(cli(["workspace", "points", "--open", "--json"]));
|
|
123
|
+
expect(res.structuredContent).toMatchObject({ open: true, sources: [], points: [], questions: [] });
|
|
124
|
+
// The generated workspace declares no answer kind, so there is nothing to answer.
|
|
125
|
+
const answered = await call(s, "points-answer", { id: "slice-tier-000000000000", answer: "small", by: ["alice"] });
|
|
126
|
+
expect(answered.structuredContent).toMatchObject({ verb: "answer", error: { code: "points-undeclared" } });
|
|
127
|
+
const bad = await call(s, "points-answer", { id: "slice-tier-000000000000", answer: "small", by: [] });
|
|
128
|
+
expect(bad.isError).toBe(true);
|
|
129
|
+
}, 120_000);
|
|
130
|
+
|
|
131
|
+
test("workspace-work-history returns the document chant workspace work history --json prints (#2785)", async () => {
|
|
132
|
+
const s = server();
|
|
133
|
+
const res = await call(s, "workspace-work-history", { item: "W-1" });
|
|
134
|
+
expect(res.isError).toBeUndefined();
|
|
135
|
+
expect(res.structuredContent).toEqual(cli(["workspace", "work", "history", "W-1", "--json"]));
|
|
136
|
+
expect(res.structuredContent).toMatchObject({ contract: 1, error: { code: expect.any(String) } });
|
|
137
|
+
const bad = await call(s, "workspace-work-history", {});
|
|
138
|
+
expect(bad.isError).toBe(true);
|
|
139
|
+
}, 120_000);
|
|
140
|
+
|
|
141
|
+
test("workspace-changes returns the document chant workspace check --changes --json prints (#2773)", async () => {
|
|
142
|
+
const s = server();
|
|
143
|
+
const res = await call(s, "workspace-changes", { range: "HEAD", severity: "fail" });
|
|
144
|
+
expect(res.isError).toBeUndefined();
|
|
145
|
+
expect(res.structuredContent).toEqual(cli(["workspace", "check", "--changes", "HEAD", "--severity", "fail", "--json"]));
|
|
146
|
+
expect(res.structuredContent).toMatchObject({ severity: "fail", paths: [], findings: [], ok: true });
|
|
147
|
+
const unknown = await call(s, "workspace-changes", { range: "HEAD", work: "W-999" });
|
|
148
|
+
expect(unknown.structuredContent).toMatchObject({ error: { code: "work-item-unknown" } });
|
|
149
|
+
const bad = await call(s, "workspace-changes", { range: "HEAD", severity: "loud" });
|
|
150
|
+
expect(bad.isError).toBe(true);
|
|
151
|
+
}, 120_000);
|
|
152
|
+
|
|
118
153
|
test("an error document is returned as a document, and a flag-shaped value is refused before chant runs", async () => {
|
|
119
154
|
const s = server();
|
|
120
155
|
const missing = await call(s, "workspace-records", { kind: "nowhere/none.kind.mjs" });
|
|
@@ -130,6 +165,7 @@ describe("reads", () => {
|
|
|
130
165
|
expect(mcpToolCall(["workspace", "graph", "--intent", "a.mjs:1", "--kind", KIND, "--json"])).toEqual({ name: "workspace-graph", arguments: { intent: "a.mjs:1", kind: [KIND] } });
|
|
131
166
|
expect(mcpToolCall(["workspace", "graph", "--composites", "--json"])).toEqual({ name: "workspace-graph", arguments: { composites: true } });
|
|
132
167
|
expect(mcpToolCall(["workspace", "check", "--format", "json"])).toBeUndefined();
|
|
168
|
+
expect(mcpToolCall(["workspace", "check", "--changes", "main..HEAD", "--work", "W-001", "--json"])).toEqual({ name: "workspace-changes", arguments: { range: "main..HEAD", work: "W-001" } });
|
|
133
169
|
});
|
|
134
170
|
});
|
|
135
171
|
|
|
@@ -173,25 +209,18 @@ describe("writes", () => {
|
|
|
173
209
|
const reasoning = await call(s, "records-amend", { kind: KIND, id: "fix-001", fields: { question: "Something else?" } });
|
|
174
210
|
expect(reasoning.structuredContent).toMatchObject({ error: { code: "amend-supersede-instead" } });
|
|
175
211
|
|
|
176
|
-
|
|
212
|
+
// A new record opens proposed (MCP forces it), so by names the proposer, in proposedBy's field, not the decider (#2756).
|
|
213
|
+
const both = await call(s, "records-new", { kind: KIND, record: { ...proposal("Two proposers"), proposed_by: "alice" }, by: "bob", dryRun: true });
|
|
177
214
|
expect(both.structuredContent).toMatchObject({ error: { code: "write-input-invalid" } });
|
|
178
|
-
const by = await call(s, "records-new", { kind: KIND, record: proposal("One
|
|
215
|
+
const by = await call(s, "records-new", { kind: KIND, record: proposal("One proposer"), by: "alice", dryRun: true });
|
|
179
216
|
expect(by.structuredContent, JSON.stringify(by.structuredContent)).toHaveProperty("text");
|
|
180
|
-
expect((by.structuredContent as { text: string }).text).toContain('
|
|
217
|
+
expect((by.structuredContent as { text: string }).text).toContain('proposed_by: "alice"');
|
|
218
|
+
expect((by.structuredContent as { text: string }).text).toContain("decided_by: null");
|
|
219
|
+
|
|
220
|
+
// --sign seals the decider, and a record by names as proposed carries no decided_by yet.
|
|
221
|
+
const signed = await call(s, "records-new", { kind: KIND, record: proposal("Signed"), by: "alice", sign: true, dryRun: true });
|
|
222
|
+
expect(signed.structuredContent).toMatchObject({ error: { code: "record-sign-failed", message: expect.stringContaining("names no decided_by") } });
|
|
181
223
|
|
|
182
|
-
// No key configured on this host: the CLI's refusal and remedy.
|
|
183
|
-
const home = { GIT_CONFIG_GLOBAL: "/dev/null", GIT_CONFIG_NOSYSTEM: "1" };
|
|
184
|
-
const saved = { ...process.env };
|
|
185
|
-
Object.assign(process.env, home);
|
|
186
|
-
try {
|
|
187
|
-
const signed = await call(s, "records-new", { kind: KIND, record: proposal("Signed"), by: "alice", sign: true, dryRun: true });
|
|
188
|
-
expect(signed.structuredContent).toMatchObject({ error: { code: "record-sign-failed", message: expect.stringContaining("pass --sign <key file>") } });
|
|
189
|
-
} finally {
|
|
190
|
-
for (const k of Object.keys(home)) {
|
|
191
|
-
if (saved[k] === undefined) delete process.env[k];
|
|
192
|
-
else process.env[k] = saved[k];
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
224
|
// Nothing above wrote a file.
|
|
196
225
|
expect(readFileSync(join(ws.dir, "decisions", "fix-001-how-the-app-is-deployed.md"), "utf-8")).toContain('question: "What declares the app\'s deployment?"');
|
|
197
226
|
}, 180_000);
|
|
@@ -6,15 +6,18 @@
|
|
|
6
6
|
* is a thin call into the code the CLI runs:
|
|
7
7
|
*
|
|
8
8
|
* - The reads (`workspace-ls`, `workspace-status`, `workspace-graph`,
|
|
9
|
-
* `workspace-
|
|
10
|
-
*
|
|
9
|
+
* `workspace-changes`, `workspace-records`, `workspace-points`,
|
|
10
|
+
* `workspace-work-history`) run `chant workspace <command>
|
|
11
|
+
* ... --json` with the chant this server runs as, in the server's
|
|
12
|
+
* directory, and return the
|
|
11
13
|
* document it printed, unchanged, with its reason codes (#2536). Running the
|
|
12
14
|
* command, rather than calling into it, keeps every rule it has, handing the
|
|
13
15
|
* read to the workspace root's pinned chant included (ws-021), and keeps
|
|
14
16
|
* anything a command prints away from the protocol on stdout.
|
|
15
17
|
* - The writes (`records-new`, `records-amend`, `records-review`,
|
|
16
|
-
* `records-close`) call the functions `chant workspace
|
|
17
|
-
* review|close` call, and return the
|
|
18
|
+
* `records-close`, `points-answer`) call the functions `chant workspace
|
|
19
|
+
* records new|amend|review|close` and `points answer` call, and return the
|
|
20
|
+
* same JSON result. They keep every rule
|
|
18
21
|
* the CLI keeps: the kind's schema, a closed record never changing, an
|
|
19
22
|
* approved one changing only as its approval rule allows, a dissent needing
|
|
20
23
|
* a note, and `sign` using this host's configured key or refusing with the
|
|
@@ -50,7 +53,7 @@ export interface WorkspaceToolsOptions {
|
|
|
50
53
|
|
|
51
54
|
const PROTOCOL =
|
|
52
55
|
"Records are proposals until they are reviewed: a new record opens proposed, and people decide it through reviews and amendments. " +
|
|
53
|
-
"by must name the person or agent that actually decided, as it is recorded as given.";
|
|
56
|
+
"by must name the person or agent that actually proposed or decided it, as it is recorded as given.";
|
|
54
57
|
|
|
55
58
|
const kindProp = {
|
|
56
59
|
type: "string",
|
|
@@ -75,7 +78,7 @@ export const workspaceReadTools: ToolDefinition[] = [
|
|
|
75
78
|
{
|
|
76
79
|
name: "workspace-status",
|
|
77
80
|
description:
|
|
78
|
-
"What each member has released to an environment, from the lifecycle ledgers: chant workspace status <env> --json. Returns that document unchanged (status.schema.json).",
|
|
81
|
+
"What each member has released to an environment, its gates, and the steward that runs it with each Op's last run, from the declaration and the lifecycle ledgers: chant workspace status <env> --json. Returns that document unchanged (status.schema.json).",
|
|
79
82
|
inputSchema: {
|
|
80
83
|
type: "object",
|
|
81
84
|
properties: {
|
|
@@ -103,10 +106,29 @@ export const workspaceReadTools: ToolDefinition[] = [
|
|
|
103
106
|
},
|
|
104
107
|
},
|
|
105
108
|
},
|
|
109
|
+
{
|
|
110
|
+
name: "workspace-changes",
|
|
111
|
+
description:
|
|
112
|
+
"The forward coverage check over a diff: chant workspace check --changes <range> --json (changes.schema.json, #2773). Each changed path with the current records whose constrains cover it, and a change-uncovered or change-out-of-scope finding for each gap, at the severity the declaration's changes block sets. Returns the document unchanged.",
|
|
113
|
+
inputSchema: {
|
|
114
|
+
type: "object",
|
|
115
|
+
properties: {
|
|
116
|
+
range: { type: "string", description: "The diff: <base>..<head>, <base>...<head> (from their merge base), or <base> alone, to HEAD (--changes)." },
|
|
117
|
+
work: { type: "string", description: "The id of the work item in hand, whose out_of_scope and whose decisions' out_of_scope apply (--work)." },
|
|
118
|
+
severity: { type: "string", enum: ["off", "warn", "fail"], description: "In place of the declaration's changes.severity (--severity)." },
|
|
119
|
+
kind: {
|
|
120
|
+
type: "array",
|
|
121
|
+
items: { type: "string" },
|
|
122
|
+
description: "Record kind files to read in place of the declared ones (--kind).",
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
required: ["range"],
|
|
126
|
+
},
|
|
127
|
+
},
|
|
106
128
|
{
|
|
107
129
|
name: "workspace-records",
|
|
108
130
|
description:
|
|
109
|
-
"The records of a kind, validated, with supersession, provenance, quorum and warnings: chant workspace records --json (records.schema.json). With since, what changed since a revision or a review session (records-since.schema.json). Returns the document unchanged; with id, only that record is kept in records. " +
|
|
131
|
+
"The records of a kind, validated, with supersession, remediation, provenance, quorum and warnings: chant workspace records --json (records.schema.json). With since, what changed since a revision or a review session (records-since.schema.json). Returns the document unchanged; with id, only that record is kept in records. " +
|
|
110
132
|
PROTOCOL,
|
|
111
133
|
inputSchema: {
|
|
112
134
|
type: "object",
|
|
@@ -119,6 +141,32 @@ export const workspaceReadTools: ToolDefinition[] = [
|
|
|
119
141
|
},
|
|
120
142
|
},
|
|
121
143
|
},
|
|
144
|
+
{
|
|
145
|
+
name: "workspace-points",
|
|
146
|
+
description:
|
|
147
|
+
"The workspace's decision points and the questions asked of them: chant workspace points --json (points.schema.json, ws-058). A question is open while it is escalated to people, or proposed by a model and not yet confirmed; each lists any model's answer with its confidence and threshold. Returns the document unchanged. chant calls no model to answer this.",
|
|
148
|
+
inputSchema: {
|
|
149
|
+
type: "object",
|
|
150
|
+
properties: {
|
|
151
|
+
open: { type: "boolean", description: "Only the open questions (--open)." },
|
|
152
|
+
kind: { type: "string", description: "One answer kind file, in place of the declared ones (--kind)." },
|
|
153
|
+
at: atProp,
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
name: "workspace-work-history",
|
|
159
|
+
description:
|
|
160
|
+
"One work item's lease history, from the lifecycle ledger of the member that owns its work kind: chant workspace work history <item> --json (work-history.schema.json, #2785). Each claim has its fencing token and holder and how it ended: released with an outcome, still held, or never released (expired, or lost to a later claim). Returns the document unchanged.",
|
|
161
|
+
inputSchema: {
|
|
162
|
+
type: "object",
|
|
163
|
+
properties: {
|
|
164
|
+
item: { type: "string", description: "The work item's id." },
|
|
165
|
+
kind: { type: "string", description: "The work kind file, when more than one declared work kind has the id (--kind)." },
|
|
166
|
+
},
|
|
167
|
+
required: ["item"],
|
|
168
|
+
},
|
|
169
|
+
},
|
|
122
170
|
];
|
|
123
171
|
|
|
124
172
|
export const workspaceWriteTools: ToolDefinition[] = [
|
|
@@ -133,7 +181,11 @@ export const workspaceWriteTools: ToolDefinition[] = [
|
|
|
133
181
|
kind: kindProp,
|
|
134
182
|
record: { type: "object", description: "The record's fields, as the kind's schema describes them. The id is allocated when left out." },
|
|
135
183
|
prefix: { type: "string", description: "The id prefix to allocate under, when the records use several (--prefix)." },
|
|
136
|
-
by: {
|
|
184
|
+
by: {
|
|
185
|
+
type: "string",
|
|
186
|
+
description:
|
|
187
|
+
"Who proposed it: written to the kind's proposedBy field, such as proposed_by, since a record opens proposed. Written to its decider field, such as decided_by, only when the record's fields open it straight into a later state. Required to sign.",
|
|
188
|
+
},
|
|
137
189
|
sign: signProp,
|
|
138
190
|
dryRun: dryRunProp,
|
|
139
191
|
},
|
|
@@ -191,6 +243,23 @@ export const workspaceWriteTools: ToolDefinition[] = [
|
|
|
191
243
|
required: ["id"],
|
|
192
244
|
},
|
|
193
245
|
},
|
|
246
|
+
{
|
|
247
|
+
name: "points-answer",
|
|
248
|
+
description:
|
|
249
|
+
"Record people's answer to an open decision point question, or confirm a model's proposal: chant workspace points answer. Refused unless the point's quorum is met: distinct people, none holding the agent role, each holding one of the quorum's roles when it names any. An answered question never changes. " +
|
|
250
|
+
PROTOCOL,
|
|
251
|
+
inputSchema: {
|
|
252
|
+
type: "object",
|
|
253
|
+
properties: {
|
|
254
|
+
id: { type: "string", description: "The question's id, as workspace-points lists it." },
|
|
255
|
+
answer: { type: ["string", "boolean"], description: "One of the question's candidates; for a noul, true or false." },
|
|
256
|
+
by: { type: "array", items: { type: "string" }, description: "Each person who answered (--by)." },
|
|
257
|
+
kind: { type: "string", description: "The answer kind file. Without it, the declared answer kinds." },
|
|
258
|
+
dryRun: dryRunProp,
|
|
259
|
+
},
|
|
260
|
+
required: ["id", "answer", "by"],
|
|
261
|
+
},
|
|
262
|
+
},
|
|
194
263
|
];
|
|
195
264
|
|
|
196
265
|
/** A tool call that can't be made as given: the client gets it as an error result, and nothing runs. */
|
|
@@ -249,6 +318,31 @@ export function readArgv(tool: string, params: Record<string, unknown>): string[
|
|
|
249
318
|
if (intent !== undefined) return ["workspace", "graph", "--intent", intent, ...kindArgs, ...atArgs, "--json"];
|
|
250
319
|
return ["workspace", "graph", ...kindArgs, ...atArgs, "--json"];
|
|
251
320
|
}
|
|
321
|
+
case "workspace-changes": {
|
|
322
|
+
const range = str(params, "range", true)!;
|
|
323
|
+
const work = str(params, "work");
|
|
324
|
+
const severity = str(params, "severity");
|
|
325
|
+
if (severity !== undefined && !["off", "warn", "fail"].includes(severity)) throw new ToolInputError("severity must be off, warn or fail");
|
|
326
|
+
return [
|
|
327
|
+
"workspace",
|
|
328
|
+
"check",
|
|
329
|
+
"--changes",
|
|
330
|
+
range,
|
|
331
|
+
...(work !== undefined ? ["--work", work] : []),
|
|
332
|
+
...(severity !== undefined ? ["--severity", severity] : []),
|
|
333
|
+
...kinds(params).flatMap((k) => ["--kind", k]),
|
|
334
|
+
"--json",
|
|
335
|
+
];
|
|
336
|
+
}
|
|
337
|
+
case "workspace-work-history": {
|
|
338
|
+
const item = str(params, "item", true)!;
|
|
339
|
+
const kind = str(params, "kind");
|
|
340
|
+
return ["workspace", "work", "history", item, ...(kind !== undefined ? ["--kind", kind] : []), "--json"];
|
|
341
|
+
}
|
|
342
|
+
case "workspace-points": {
|
|
343
|
+
const kind = str(params, "kind");
|
|
344
|
+
return ["workspace", "points", ...(bool(params, "open") ? ["--open"] : []), ...(kind !== undefined ? ["--kind", kind] : []), ...atArgs, "--json"];
|
|
345
|
+
}
|
|
252
346
|
case "workspace-records": {
|
|
253
347
|
const kind = str(params, "kind");
|
|
254
348
|
const since = str(params, "since");
|
|
@@ -389,6 +483,14 @@ export function createWorkspaceTools(options: WorkspaceToolsOptions): WorkspaceT
|
|
|
389
483
|
cwd,
|
|
390
484
|
});
|
|
391
485
|
},
|
|
486
|
+
"points-answer": async (params) => {
|
|
487
|
+
const { answerPoint } = await import("../../workspace/decide");
|
|
488
|
+
const answer = params.answer;
|
|
489
|
+
if (typeof answer !== "string" && typeof answer !== "boolean") throw new ToolInputError("answer must be a string, or true or false");
|
|
490
|
+
const by = params.by;
|
|
491
|
+
if (!Array.isArray(by) || by.length === 0 || !by.every((b) => typeof b === "string" && b.trim() !== "")) throw new ToolInputError("by must list each person who answered");
|
|
492
|
+
return answerPoint({ cwd, id: str(params, "id", true)!, answer, by: by as string[], kind: str(params, "kind"), dryRun: bool(params, "dryRun") });
|
|
493
|
+
},
|
|
392
494
|
"records-close": async (params) => {
|
|
393
495
|
const w = await write();
|
|
394
496
|
const { closeRecord, RECORDS_CLOSE_SCHEMA_ID } = await import("../../workspace/records-close");
|
package/src/cli/plugins.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { importLexiconModule, lexiconModulePath, lexiconNames, registerLexiconDeclarations } from "../lexicon-module";
|
|
1
|
+
import { importLexiconModule, importLexiconPackage, lexiconModulePath, lexiconNames, registerLexiconDeclarations, resolveFromProject } from "../lexicon-module";
|
|
2
2
|
import { readLexiconDeclarationsStatically, type StaticLexiconRead } from "../config-static";
|
|
3
3
|
export { unknownPathLexiconsNotice } from "../config-static";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
@@ -51,7 +51,7 @@ export async function loadPlugin(lexiconName: string): Promise<LexiconPlugin> {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
const packageName = `@intentius/chant-lexicon-${lexiconName}`;
|
|
54
|
-
const mod = await
|
|
54
|
+
const mod = (await importLexiconPackage(packageName)) as Record<string, any>;
|
|
55
55
|
|
|
56
56
|
// Look for an explicit LexiconPlugin export
|
|
57
57
|
for (const value of Object.values(mod)) {
|
|
@@ -109,7 +109,15 @@ export function resolveLexiconVersions(lexiconNames: readonly string[]): Record<
|
|
|
109
109
|
if (lexiconModulePath(name) !== undefined) continue;
|
|
110
110
|
const packageName = `@intentius/chant-lexicon-${name}`;
|
|
111
111
|
try {
|
|
112
|
-
|
|
112
|
+
// chant#2845 — a lexicon chant's own install can't reach is resolved from the project.
|
|
113
|
+
let entry: string | undefined;
|
|
114
|
+
try {
|
|
115
|
+
entry = require_.resolve(packageName);
|
|
116
|
+
} catch (err) {
|
|
117
|
+
entry = resolveFromProject(packageName);
|
|
118
|
+
if (entry === undefined) throw err;
|
|
119
|
+
}
|
|
120
|
+
let dir = dirname(entry);
|
|
113
121
|
// Bounded walk — a resolved entry point is never deeply nested inside
|
|
114
122
|
// its own package, and an unbounded loop here would climb to `/`.
|
|
115
123
|
for (let depth = 0; depth < 10; depth++) {
|
package/src/cli/registry.ts
CHANGED
|
@@ -287,17 +287,39 @@ export interface ParsedArgs {
|
|
|
287
287
|
kind?: string;
|
|
288
288
|
/** Every `--kind` given, in order: `chant workspace graph --intent` reads each (#2651). */
|
|
289
289
|
kinds?: string[];
|
|
290
|
+
/** Every `--by` given, in order: `chant workspace points answer` counts each person toward the quorum (#2739). */
|
|
291
|
+
bys?: string[];
|
|
292
|
+
/** `chant workspace points --open` (#2739): only the questions still open. */
|
|
293
|
+
open?: boolean;
|
|
294
|
+
/** `chant workspace points ask <point> --inputs <file|->` (#2739): the inputs, as a JSON object. */
|
|
295
|
+
inputs?: string;
|
|
296
|
+
/** `chant workspace points ask <point> --response <file>` (#2739): a POST /v1/systemone response the caller got from a backend. */
|
|
297
|
+
response?: string;
|
|
298
|
+
/** `chant workspace points ask <point> --subject <id>` (#2739): what the question is about. */
|
|
299
|
+
subject?: string;
|
|
300
|
+
/** `chant workspace points answer <id> --answer <value>` (#2739): the people's answer. */
|
|
301
|
+
answer?: string;
|
|
290
302
|
/** `chant workspace graph --composites` (#2662): print each composite instance with the components that can deploy it. */
|
|
291
303
|
composites?: boolean;
|
|
292
304
|
/** `chant workspace graph --intent <path[:start-end]>` (#2651): the region the intent graph is over. */
|
|
293
305
|
intent?: string;
|
|
306
|
+
/** `chant workspace check --changes <base>..<head>` (#2773): the diff the forward coverage check maps to records. */
|
|
307
|
+
changes?: string;
|
|
308
|
+
/** `chant workspace check --changes ... --severity off|warn|fail` (#2773): in place of the declaration's `changes.severity`. */
|
|
309
|
+
severity?: string;
|
|
294
310
|
/** `chant workspace records --current` (#2546): leave out records a closed record supersedes. */
|
|
295
311
|
current?: boolean;
|
|
296
312
|
/** `chant workspace records amend <id> --set <file|->` (#2670): the JSON fields to set. */
|
|
297
313
|
set?: string;
|
|
298
314
|
/** `chant workspace records review <id> --verdict <v>` (#2670): agree, dissent or abstain. */
|
|
299
315
|
verdict?: string;
|
|
300
|
-
/**
|
|
316
|
+
/**
|
|
317
|
+
* `chant workspace records review <id> --by <principal>` (#2670): the
|
|
318
|
+
* reviewer, as the caller names them. Also `chant workspace records new
|
|
319
|
+
* --by <name>` (#2756): the record's proposer, or its decider when it
|
|
320
|
+
* opens straight into a later state; see {@link ChannelOptions.by} in
|
|
321
|
+
* `records-write.ts`.
|
|
322
|
+
*/
|
|
301
323
|
by?: string;
|
|
302
324
|
/**
|
|
303
325
|
* `chant workspace records review <id> --sign [<key file>]` (#2687): the key that seals the verdict, or true for git's user.signingkey.
|
|
@@ -369,6 +391,8 @@ export interface ParsedArgs {
|
|
|
369
391
|
component?: string;
|
|
370
392
|
/** `chant components release record --digest <sha256:...>` (#568) — artifact digest to record, joining this release to the build archive/ledger. Also `chant components export --digest <manifestDigest>` (#929) — a build archive manifest digest to export directly, bypassing env/component resolution. */
|
|
371
393
|
digest?: string;
|
|
394
|
+
/** `chant components release record --release-plan <file>` (ws-055, #2733) — path to a release plan JSON file, persisted content-addressed to `_plans/<digest>.json` on chant/lifecycle and read back through the read contract (`chant workspace status --json`). The plan's own `digest` field supplies `--digest` when it is omitted, and must match it when both are given. Distinct from `--plan` (#2300, below), the Op gate-approval plan digest. */
|
|
395
|
+
releasePlanFile?: string;
|
|
372
396
|
/** Every `--digest` value, in order (#2602). `chant components promote --digest <component>=<sha256:...>` is repeatable, one per component; the other commands read the single {@link digest}. */
|
|
373
397
|
digests?: string[];
|
|
374
398
|
/** `chant components release record --git-sha <sha>` (#568) — git commit the deploy was built from. */
|
|
@@ -413,6 +437,23 @@ export interface ParsedArgs {
|
|
|
413
437
|
interval?: string;
|
|
414
438
|
/** `chant operator --lease-ttl <duration>` (#1485) — how long an acquired lease is valid before it's reclaimable by another operator. Default: 5m. */
|
|
415
439
|
leaseTtl?: string;
|
|
440
|
+
/**
|
|
441
|
+
* `chant operator --steward [<name>]` (#2731) — run a declared steward's
|
|
442
|
+
* local form: its scheduled Ops on their crons, under the steward's own
|
|
443
|
+
* lease. `""` when the flag is given without a name, which picks the
|
|
444
|
+
* project's only steward.
|
|
445
|
+
*/
|
|
446
|
+
steward?: string;
|
|
447
|
+
/** `chant workspace work claim|renew|release <id> --holder <name>` (#2732): who holds, or releases, the work lease. */
|
|
448
|
+
holder?: string;
|
|
449
|
+
/** `chant run <op> --work <id>` (#2748): the work item an Op with a work lease runs under. `chant workspace check --changes --work <id>` (#2773): the work item in hand. */
|
|
450
|
+
work?: string;
|
|
451
|
+
/** `chant workspace work claim|renew <id> --ttl <seconds|duration>` (#2732): how long the lease lasts unless renewed. */
|
|
452
|
+
ttl?: string;
|
|
453
|
+
/** `chant workspace work renew|release <id> --token <token>` (#2732): the fencing token the caller holds. */
|
|
454
|
+
token?: string;
|
|
455
|
+
/** `chant workspace work release <id> --outcome <text>` (#2732): how the work ended, such as done or not_done. */
|
|
456
|
+
outcome?: string;
|
|
416
457
|
/** `chant operator --once` (#1485) — run a single round and exit, instead of looping until Ctrl-C. Also the offline test/cron-invoker story. */
|
|
417
458
|
once?: boolean;
|
|
418
459
|
/** `chant approve <op> <gate> --note <text>` (#1485) — optional free-text prose recorded on the gate-resolution fact. The PR link belongs in `--url` since #2028; this is for everything that isn't the link. */
|
|
@@ -26,6 +26,7 @@ import { join } from "path";
|
|
|
26
26
|
import { regenLexicon, type RegenResult } from "./lexicon-regen";
|
|
27
27
|
import { fetchWithRetry } from "./fetch";
|
|
28
28
|
import { isLexiconPlugin, type UpstreamPin } from "../lexicon";
|
|
29
|
+
import { importLexiconPackage } from "../lexicon-module";
|
|
29
30
|
|
|
30
31
|
// ── Public types ──────────────────────────────────────────────────────
|
|
31
32
|
|
|
@@ -200,7 +201,7 @@ export function revertVersionBump(filePath: string, original: string): void {
|
|
|
200
201
|
export async function loadUpstreamPin(lexicon: LexiconId): Promise<UpstreamPin | null> {
|
|
201
202
|
let mod: Record<string, unknown>;
|
|
202
203
|
try {
|
|
203
|
-
mod = (await
|
|
204
|
+
mod = (await importLexiconPackage(`@intentius/chant-lexicon-${lexicon}`)) as Record<string, unknown>;
|
|
204
205
|
} catch {
|
|
205
206
|
return null;
|
|
206
207
|
}
|