@intentius/chant 0.91.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/graph.d.ts.map +1 -1
- package/dist/cli/handlers/operator.d.ts +6 -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 +2 -1
- 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 +12 -2
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/codegen/pinned-upgrade.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/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/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 +201 -0
- 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/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 +11 -4
- package/dist/op/index.d.ts.map +1 -1
- package/dist/op/local-executor.d.ts +29 -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 +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/operator.d.ts +97 -1
- package/dist/op/operator.d.ts.map +1 -1
- package/dist/op/runtime.d.ts +37 -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/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 +22 -1
- package/dist/op/steward.d.ts.map +1 -1
- package/dist/op/types.d.ts +7 -0
- package/dist/op/types.d.ts.map +1 -1
- package/dist/op/work-lease-run.d.ts +1 -1
- package/dist/op/work-lease-run.d.ts.map +1 -1
- 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/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/boxes.d.ts +34 -1
- package/dist/workspace/checks/boxes.d.ts.map +1 -1
- 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 +7 -0
- package/dist/workspace/checks/records.d.ts.map +1 -1
- package/dist/workspace/checks.d.ts +3 -0
- 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 +49 -4
- package/dist/workspace/decide.d.ts.map +1 -1
- package/dist/workspace/declaration.d.ts +52 -0
- package/dist/workspace/declaration.d.ts.map +1 -1
- package/dist/workspace/declaration.schema.json +114 -1
- package/dist/workspace/declared-kinds.d.ts +20 -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.map +1 -1
- package/dist/workspace/points.d.ts +1 -1
- package/dist/workspace/reason-codes.d.ts +14 -2
- package/dist/workspace/reason-codes.d.ts.map +1 -1
- package/dist/workspace/records-cli.d.ts +11 -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 +34 -4
- 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 +59 -1
- package/dist/workspace/status-stewards.d.ts.map +1 -1
- package/dist/workspace/status.d.ts +16 -0
- package/dist/workspace/status.d.ts.map +1 -1
- package/dist/workspace/work-cli.d.ts +113 -2
- package/dist/workspace/work-cli.d.ts.map +1 -1
- 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/graph.test.ts +20 -0
- package/src/cli/handlers/graph.ts +16 -2
- package/src/cli/handlers/operator.ts +34 -2
- package/src/cli/handlers/run.test.ts +154 -2
- package/src/cli/handlers/run.ts +121 -2
- package/src/cli/main.test.ts +10 -0
- package/src/cli/main.ts +19 -0
- package/src/cli/mcp/workspace-tools.test.ts +35 -19
- package/src/cli/mcp/workspace-tools.ts +62 -4
- package/src/cli/plugins.ts +11 -3
- package/src/cli/registry.ts +12 -2
- 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/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/run-ledger.ts +6 -0
- package/src/lifecycle/symptoms.ts +95 -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 +119 -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/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 +18 -3
- package/src/op/local-executor.ts +151 -15
- package/src/op/local-output.test.ts +33 -0
- package/src/op/local-output.ts +20 -2
- package/src/op/op-ir.test.ts +10 -0
- package/src/op/op-ir.ts +4 -0
- package/src/op/op-verb-class.ts +1 -0
- package/src/op/operator.ts +290 -11
- package/src/op/runtime.ts +31 -8
- package/src/op/runtimes/local.ts +3 -1
- package/src/op/source-archive.ts +161 -0
- 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 +87 -3
- package/src/op/steward.ts +25 -1
- package/src/op/types.ts +7 -0
- package/src/op/work-lease-run.test.ts +20 -1
- package/src/op/work-lease-run.ts +2 -2
- 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/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 +4 -2
- package/src/workspace/check.schema.json +15 -5
- package/src/workspace/checks/boxes.test.ts +80 -1
- package/src/workspace/checks/boxes.ts +136 -1
- package/src/workspace/checks/diagrams.test.ts +134 -0
- package/src/workspace/checks/diagrams.ts +108 -0
- package/src/workspace/checks/records.ts +47 -0
- package/src/workspace/checks.ts +8 -1
- 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 +1 -1
- package/src/workspace/decide.ts +156 -23
- package/src/workspace/declaration.schema.json +114 -1
- package/src/workspace/declaration.test.ts +58 -0
- package/src/workspace/declaration.ts +104 -0
- package/src/workspace/declared-kinds.test.ts +5 -5
- package/src/workspace/declared-kinds.ts +46 -1
- 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 +8 -2
- 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/points-cli.ts +14 -3
- package/src/workspace/points-write.schema.json +11 -1
- package/src/workspace/points.schema.json +33 -0
- package/src/workspace/points.test.ts +1 -1
- package/src/workspace/points.ts +1 -1
- package/src/workspace/read-contract.test.ts +1 -1
- package/src/workspace/reason-codes.test.ts +11 -1
- package/src/workspace/reason-codes.ts +18 -2
- package/src/workspace/records-amend.schema.json +2 -0
- package/src/workspace/records-cli.ts +13 -3
- package/src/workspace/records-close.schema.json +2 -0
- 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 +36 -2
- package/src/workspace/records.test.ts +48 -3
- package/src/workspace/records.ts +109 -3
- package/src/workspace/status-contract.test.ts +13 -8
- package/src/workspace/status-gates.ts +9 -4
- package/src/workspace/status-stewards.ts +108 -4
- package/src/workspace/status.schema.json +111 -7
- package/src/workspace/status.ts +36 -1
- package/src/workspace/work-acceptance.test.ts +274 -0
- package/src/workspace/{work-cli.test.ts → work-cli.e2e.test.ts} +1 -1
- package/src/workspace/work-cli.ts +193 -10
- 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.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
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://intentius.io/chant/schemas/workspace/work-evidence/v1/work-evidence.schema.json",
|
|
4
|
+
"title": "workEvidence result",
|
|
5
|
+
"description": "What attachWorkEvidence, which the workEvidence Op activity runs, returns (#2772): the evidence entry it appended to a work item's acceptance criterion, under the run's work lease, or the reason nothing was written. Version 1. The activity returns the result and fails its step with the refusal's code. Readers ignore fields they do not know; a field is only ever added within a version. The error codes are a closed list, each in the one closed list of `reason-codes.ts`.",
|
|
6
|
+
"oneOf": [
|
|
7
|
+
{
|
|
8
|
+
"$ref": "#/$defs/result"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"$ref": "#/$defs/failure"
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"$defs": {
|
|
15
|
+
"result": {
|
|
16
|
+
"description": "The entry was appended to the record's pins field, through records amend.",
|
|
17
|
+
"type": "object",
|
|
18
|
+
"required": [
|
|
19
|
+
"$schema",
|
|
20
|
+
"contract",
|
|
21
|
+
"item",
|
|
22
|
+
"kind",
|
|
23
|
+
"path",
|
|
24
|
+
"evidence",
|
|
25
|
+
"acceptance"
|
|
26
|
+
],
|
|
27
|
+
"properties": {
|
|
28
|
+
"$schema": {
|
|
29
|
+
"const": "https://intentius.io/chant/schemas/workspace/work-evidence/v1/work-evidence.schema.json"
|
|
30
|
+
},
|
|
31
|
+
"contract": {
|
|
32
|
+
"const": 1
|
|
33
|
+
},
|
|
34
|
+
"item": {
|
|
35
|
+
"type": "string",
|
|
36
|
+
"description": "The work item's id."
|
|
37
|
+
},
|
|
38
|
+
"kind": {
|
|
39
|
+
"type": "string",
|
|
40
|
+
"description": "The work kind file, from the repository root."
|
|
41
|
+
},
|
|
42
|
+
"path": {
|
|
43
|
+
"type": "string",
|
|
44
|
+
"description": "The work record, from the repository root."
|
|
45
|
+
},
|
|
46
|
+
"evidence": {
|
|
47
|
+
"type": "object",
|
|
48
|
+
"description": "The entry appended: a title, a url or a path pinned by sha256, as_of, and the criterion, its verification, the result and by, the lease holder.",
|
|
49
|
+
"required": [
|
|
50
|
+
"title",
|
|
51
|
+
"criterion",
|
|
52
|
+
"verification",
|
|
53
|
+
"result",
|
|
54
|
+
"by"
|
|
55
|
+
],
|
|
56
|
+
"properties": {
|
|
57
|
+
"title": {
|
|
58
|
+
"type": "string"
|
|
59
|
+
},
|
|
60
|
+
"url": {
|
|
61
|
+
"type": "string"
|
|
62
|
+
},
|
|
63
|
+
"path": {
|
|
64
|
+
"type": "string"
|
|
65
|
+
},
|
|
66
|
+
"sha256": {
|
|
67
|
+
"type": "string",
|
|
68
|
+
"pattern": "^[0-9a-f]{64}$"
|
|
69
|
+
},
|
|
70
|
+
"as_of": {
|
|
71
|
+
"type": "string"
|
|
72
|
+
},
|
|
73
|
+
"criterion": {
|
|
74
|
+
"type": "string"
|
|
75
|
+
},
|
|
76
|
+
"verification": {
|
|
77
|
+
"enum": [
|
|
78
|
+
"unit",
|
|
79
|
+
"integration",
|
|
80
|
+
"e2e",
|
|
81
|
+
"runtime"
|
|
82
|
+
],
|
|
83
|
+
"description": "The criterion's verification. Never manual: a run under the lease is the implementer."
|
|
84
|
+
},
|
|
85
|
+
"result": {
|
|
86
|
+
"enum": [
|
|
87
|
+
"pass",
|
|
88
|
+
"fail"
|
|
89
|
+
]
|
|
90
|
+
},
|
|
91
|
+
"by": {
|
|
92
|
+
"type": "string",
|
|
93
|
+
"description": "The lease holder that attached it."
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
"acceptance": {
|
|
98
|
+
"type": "object",
|
|
99
|
+
"description": "The record's criteria with the entry counted, as records --json reports them.",
|
|
100
|
+
"required": [
|
|
101
|
+
"met",
|
|
102
|
+
"total",
|
|
103
|
+
"criteria"
|
|
104
|
+
],
|
|
105
|
+
"properties": {
|
|
106
|
+
"met": {
|
|
107
|
+
"type": "integer",
|
|
108
|
+
"minimum": 0
|
|
109
|
+
},
|
|
110
|
+
"total": {
|
|
111
|
+
"type": "integer",
|
|
112
|
+
"minimum": 0
|
|
113
|
+
},
|
|
114
|
+
"criteria": {
|
|
115
|
+
"type": "array",
|
|
116
|
+
"items": {
|
|
117
|
+
"type": "object",
|
|
118
|
+
"required": [
|
|
119
|
+
"id",
|
|
120
|
+
"verification",
|
|
121
|
+
"met"
|
|
122
|
+
],
|
|
123
|
+
"properties": {
|
|
124
|
+
"id": {
|
|
125
|
+
"type": "string"
|
|
126
|
+
},
|
|
127
|
+
"verification": {
|
|
128
|
+
"enum": [
|
|
129
|
+
"unit",
|
|
130
|
+
"integration",
|
|
131
|
+
"e2e",
|
|
132
|
+
"runtime",
|
|
133
|
+
"manual"
|
|
134
|
+
]
|
|
135
|
+
},
|
|
136
|
+
"met": {
|
|
137
|
+
"type": "boolean"
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
"error": false
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
"failure": {
|
|
148
|
+
"description": "Nothing was written: the input, the item, the criterion or the lease refused it, or records amend did.",
|
|
149
|
+
"type": "object",
|
|
150
|
+
"required": [
|
|
151
|
+
"$schema",
|
|
152
|
+
"contract",
|
|
153
|
+
"error"
|
|
154
|
+
],
|
|
155
|
+
"properties": {
|
|
156
|
+
"$schema": {
|
|
157
|
+
"const": "https://intentius.io/chant/schemas/workspace/work-evidence/v1/work-evidence.schema.json"
|
|
158
|
+
},
|
|
159
|
+
"contract": {
|
|
160
|
+
"const": 1
|
|
161
|
+
},
|
|
162
|
+
"error": {
|
|
163
|
+
"type": "object",
|
|
164
|
+
"required": [
|
|
165
|
+
"code",
|
|
166
|
+
"message"
|
|
167
|
+
],
|
|
168
|
+
"properties": {
|
|
169
|
+
"code": {
|
|
170
|
+
"enum": [
|
|
171
|
+
"kind-unreadable",
|
|
172
|
+
"kind-invalid",
|
|
173
|
+
"schema-unreadable",
|
|
174
|
+
"schema-id-mismatch",
|
|
175
|
+
"schema-invalid",
|
|
176
|
+
"location-missing",
|
|
177
|
+
"write-usage-invalid",
|
|
178
|
+
"write-input-invalid",
|
|
179
|
+
"record-not-found",
|
|
180
|
+
"amend-id-immutable",
|
|
181
|
+
"record-closed",
|
|
182
|
+
"amend-supersede-instead",
|
|
183
|
+
"record-sign-failed",
|
|
184
|
+
"record-unparseable",
|
|
185
|
+
"record-schema-invalid",
|
|
186
|
+
"record-id-duplicate",
|
|
187
|
+
"record-supersedes-unknown",
|
|
188
|
+
"record-supersedes-conflict",
|
|
189
|
+
"session-seal-mismatch",
|
|
190
|
+
"session-verdict-unknown-record",
|
|
191
|
+
"work-kind-missing",
|
|
192
|
+
"work-kind-ambiguous",
|
|
193
|
+
"work-item-unknown",
|
|
194
|
+
"work-item-closed",
|
|
195
|
+
"work-criterion-unknown",
|
|
196
|
+
"work-acceptance-self-verified",
|
|
197
|
+
"lease-held",
|
|
198
|
+
"lease-not-held",
|
|
199
|
+
"lease-token-mismatch",
|
|
200
|
+
"not-a-git-repository"
|
|
201
|
+
]
|
|
202
|
+
},
|
|
203
|
+
"message": {
|
|
204
|
+
"type": "string"
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
"evidence": false
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evidence attached to a work item's acceptance criterion by the run that
|
|
3
|
+
* holds its lease (#2772).
|
|
4
|
+
*
|
|
5
|
+
* A work kind with acceptance criteria (`work.acceptance` in the kind, read in
|
|
6
|
+
* `./work.ts`) lists what done means on the record: each criterion has an id,
|
|
7
|
+
* its text and the verification it expects. Evidence in the kind's pins field
|
|
8
|
+
* meets a criterion when it names it, carries `result: pass` and has the
|
|
9
|
+
* criterion's verification. {@link attachWorkEvidence} appends one such entry
|
|
10
|
+
* for a run under the item's work lease (an Op with `workLease`, #2748, such
|
|
11
|
+
* as a steward's), through `records amend`, so the record is written the way
|
|
12
|
+
* a person's amendment writes it.
|
|
13
|
+
*
|
|
14
|
+
* It writes only for the lease's holder, under the token the run was given:
|
|
15
|
+
* a run whose lease expired or went to someone else is refused, as a renewal
|
|
16
|
+
* would be. It refuses a criterion the record doesn't list, and a `manual`
|
|
17
|
+
* one: the run holding the lease is the item's implementer, and a manual
|
|
18
|
+
* verdict comes from someone else. A person records that verdict with
|
|
19
|
+
* `records amend`, naming themselves in `by`.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { relative, sep } from "node:path";
|
|
23
|
+
import { activeWorkLeases } from "../lifecycle/work-lease";
|
|
24
|
+
import type { ReasonCode } from "./reason-codes";
|
|
25
|
+
import { pinFile } from "./records-cli";
|
|
26
|
+
import { AMEND_ERROR_CODES, amendRecord } from "./records-write";
|
|
27
|
+
import { acceptanceCriteria, EVIDENCE_RESULTS, workAcceptance, type EvidenceResult, type VerificationType, type WorkAcceptance } from "./work";
|
|
28
|
+
import { findWorkItem, WorkError } from "./work-cli";
|
|
29
|
+
|
|
30
|
+
/** Why evidence was not attached. Closed. Nothing is written with any of them. */
|
|
31
|
+
export const WORK_EVIDENCE_ERROR_CODES = [
|
|
32
|
+
...AMEND_ERROR_CODES,
|
|
33
|
+
"work-kind-missing",
|
|
34
|
+
"work-kind-ambiguous",
|
|
35
|
+
"work-item-unknown",
|
|
36
|
+
"work-item-closed",
|
|
37
|
+
"work-criterion-unknown",
|
|
38
|
+
"work-acceptance-self-verified",
|
|
39
|
+
"lease-held",
|
|
40
|
+
"lease-not-held",
|
|
41
|
+
"lease-token-mismatch",
|
|
42
|
+
"not-a-git-repository",
|
|
43
|
+
] as const satisfies readonly ReasonCode[];
|
|
44
|
+
export type WorkEvidenceErrorCode = (typeof WORK_EVIDENCE_ERROR_CODES)[number];
|
|
45
|
+
|
|
46
|
+
export interface AttachWorkEvidenceRequest {
|
|
47
|
+
/** Where the workspace is found, and what `path` and `kind` resolve against. */
|
|
48
|
+
cwd: string;
|
|
49
|
+
/** The work item. */
|
|
50
|
+
item: string;
|
|
51
|
+
/** The work kind file, when the declaration names more than one with the item. */
|
|
52
|
+
kind?: string;
|
|
53
|
+
/** The lease the run holds: its holder and fencing token. */
|
|
54
|
+
holder: string;
|
|
55
|
+
token: string;
|
|
56
|
+
/** The criterion the evidence is for, by id. */
|
|
57
|
+
criterion: string;
|
|
58
|
+
result: EvidenceResult;
|
|
59
|
+
title: string;
|
|
60
|
+
/** A public link, or */
|
|
61
|
+
url?: string;
|
|
62
|
+
/** a workspace file, pinned by the hash of its bytes now. */
|
|
63
|
+
path?: string;
|
|
64
|
+
/** When the evidence was taken, as an ISO 8601 timestamp. Now by default. */
|
|
65
|
+
asOf?: string;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** The version of the attach document this chant writes. */
|
|
69
|
+
export const WORK_EVIDENCE_CONTRACT_VERSION = 1;
|
|
70
|
+
|
|
71
|
+
/** `$id` of the JSON Schema for the attach document, shipped beside this file. */
|
|
72
|
+
export const WORK_EVIDENCE_OUTPUT_SCHEMA_ID = "https://intentius.io/chant/schemas/workspace/work-evidence/v1/work-evidence.schema.json";
|
|
73
|
+
|
|
74
|
+
interface DocHead {
|
|
75
|
+
$schema: string;
|
|
76
|
+
contract: number;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** What {@link attachWorkEvidence} returns: the entry written, or why nothing was. */
|
|
80
|
+
export type WorkEvidenceDocument = DocHead &
|
|
81
|
+
(
|
|
82
|
+
| {
|
|
83
|
+
item: string;
|
|
84
|
+
/** The work kind file, from the repository root. */
|
|
85
|
+
kind: string;
|
|
86
|
+
/** The record, from the repository root. */
|
|
87
|
+
path: string;
|
|
88
|
+
/** The entry appended to the kind's pins field. */
|
|
89
|
+
evidence: Record<string, unknown>;
|
|
90
|
+
/** The record's criteria with the new entry counted. */
|
|
91
|
+
acceptance: WorkAcceptance;
|
|
92
|
+
}
|
|
93
|
+
| { error: { code: WorkEvidenceErrorCode; message: string } }
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
class EvidenceError extends Error {
|
|
97
|
+
constructor(
|
|
98
|
+
readonly code: WorkEvidenceErrorCode,
|
|
99
|
+
message: string,
|
|
100
|
+
) {
|
|
101
|
+
super(message);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Append one piece of evidence for a criterion to a leased work item. Never throws for a refusal. */
|
|
106
|
+
export async function attachWorkEvidence(req: AttachWorkEvidenceRequest): Promise<WorkEvidenceDocument> {
|
|
107
|
+
const head = { $schema: WORK_EVIDENCE_OUTPUT_SCHEMA_ID, contract: WORK_EVIDENCE_CONTRACT_VERSION };
|
|
108
|
+
try {
|
|
109
|
+
if (typeof req.criterion !== "string" || req.criterion === "") throw new EvidenceError("write-usage-invalid", "the evidence names no criterion");
|
|
110
|
+
if (!(EVIDENCE_RESULTS as readonly string[]).includes(req.result)) {
|
|
111
|
+
throw new EvidenceError("write-usage-invalid", `result is pass or fail, not ${JSON.stringify(req.result)}`);
|
|
112
|
+
}
|
|
113
|
+
if (typeof req.title !== "string" || req.title.trim() === "") throw new EvidenceError("write-usage-invalid", "the evidence has no title");
|
|
114
|
+
if ((req.url === undefined) === (req.path === undefined)) throw new EvidenceError("write-usage-invalid", "the evidence is a url or a path, exactly one of them");
|
|
115
|
+
if (req.url !== undefined && !req.url.startsWith("https://")) throw new EvidenceError("write-input-invalid", `evidence links are https://, not ${JSON.stringify(req.url)}`);
|
|
116
|
+
|
|
117
|
+
const found = await findWorkItem(req.item, req.cwd, req.kind);
|
|
118
|
+
const { kind } = found.loaded;
|
|
119
|
+
const data = found.record.data;
|
|
120
|
+
if (found.state !== null && (kind.closedStates ?? []).includes(found.state)) {
|
|
121
|
+
throw new EvidenceError("work-item-closed", `${req.item} is ${found.state}, a closed state, so no evidence is added to it`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// The lease, as the local refs hold it: the run claimed it here, so they are current.
|
|
125
|
+
const lease = (await activeWorkLeases(found.loaded.file)).get(req.item);
|
|
126
|
+
if (!lease) throw new EvidenceError("lease-not-held", `nobody holds a live lease on ${req.item}: it expired, was released or was never claimed`);
|
|
127
|
+
if (lease.holder !== req.holder) throw new EvidenceError("lease-held", `${lease.holder} holds the lease on ${req.item}, not ${req.holder}`);
|
|
128
|
+
if (lease.token !== req.token) throw new EvidenceError("lease-token-mismatch", `the lease on ${req.item} carries another token than the one given: it changed hands`);
|
|
129
|
+
|
|
130
|
+
const spec = kind.work?.acceptance;
|
|
131
|
+
if (!spec || !kind.pins) throw new EvidenceError("work-criterion-unknown", `the ${kind.name} kind has no acceptance criteria, so evidence can't name ${req.criterion}`);
|
|
132
|
+
const criterion = acceptanceCriteria(data, spec.field).find((c) => c.id === req.criterion);
|
|
133
|
+
if (!criterion) throw new EvidenceError("work-criterion-unknown", `${req.item} lists no acceptance criterion ${req.criterion}`);
|
|
134
|
+
if (criterion.verification === "manual") {
|
|
135
|
+
throw new EvidenceError(
|
|
136
|
+
"work-acceptance-self-verified",
|
|
137
|
+
`${req.criterion} is verified by a person, and ${req.holder} holds ${req.item}'s lease, so it is the implementer: a manual verdict comes from someone else, with records amend`,
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
let pin: Record<string, unknown>;
|
|
142
|
+
if (req.path !== undefined) {
|
|
143
|
+
const pinned = pinFile(req.path, req.cwd);
|
|
144
|
+
if ("error" in pinned) throw new EvidenceError("write-input-invalid", pinned.error);
|
|
145
|
+
pin = { path: pinned.path, sha256: pinned.sha256 };
|
|
146
|
+
} else {
|
|
147
|
+
pin = { url: req.url };
|
|
148
|
+
}
|
|
149
|
+
const entry: Record<string, unknown> = {
|
|
150
|
+
title: req.title,
|
|
151
|
+
...pin,
|
|
152
|
+
as_of: req.asOf ?? new Date().toISOString(),
|
|
153
|
+
criterion: criterion.id,
|
|
154
|
+
verification: criterion.verification as VerificationType,
|
|
155
|
+
result: req.result,
|
|
156
|
+
by: req.holder,
|
|
157
|
+
};
|
|
158
|
+
const before = Array.isArray(data?.[kind.pins.field]) ? (data![kind.pins.field] as unknown[]) : [];
|
|
159
|
+
const evidence = [...before, entry];
|
|
160
|
+
const amended = await amendRecord({ kind: found.loaded.file, id: req.item, fields: JSON.stringify({ [kind.pins.field]: evidence }), cwd: req.cwd });
|
|
161
|
+
if ("error" in amended) throw new EvidenceError(amended.error.code, amended.error.message);
|
|
162
|
+
const { acceptance } = workAcceptance({ ...data, [kind.pins.field]: evidence }, spec, kind.pins.field);
|
|
163
|
+
const kindPath = relative(found.root, found.loaded.file).split(sep).join("/");
|
|
164
|
+
return { ...head, item: req.item, kind: kindPath, path: amended.path, evidence: entry, acceptance: acceptance! };
|
|
165
|
+
} catch (err) {
|
|
166
|
+
if (err instanceof EvidenceError || err instanceof WorkError) return { ...head, error: { code: err.code, message: err.message } };
|
|
167
|
+
throw err;
|
|
168
|
+
}
|
|
169
|
+
}
|