@intentius/chant 0.79.0 → 0.81.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/audit/core.d.ts.map +1 -1
- package/dist/audit/discover.d.ts +30 -0
- package/dist/audit/discover.d.ts.map +1 -1
- package/dist/audit/report-html.d.ts +5 -0
- package/dist/audit/report-html.d.ts.map +1 -1
- package/dist/audit/report-model.d.ts +13 -0
- package/dist/audit/report-model.d.ts.map +1 -1
- package/dist/audit/terraform-state.d.ts +13 -0
- package/dist/audit/terraform-state.d.ts.map +1 -1
- package/dist/cli/command-group.d.ts +6 -0
- package/dist/cli/command-group.d.ts.map +1 -1
- package/dist/cli/commands/audit.d.ts +44 -3
- package/dist/cli/commands/audit.d.ts.map +1 -1
- package/dist/cli/commands/check-lexicon-examples.d.ts.map +1 -1
- package/dist/cli/commands/check-lexicon.d.ts +8 -0
- package/dist/cli/commands/check-lexicon.d.ts.map +1 -1
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/import-agents.d.ts.map +1 -1
- package/dist/cli/commands/init.d.ts +6 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/lint.d.ts.map +1 -1
- package/dist/cli/commands/onboard.d.ts.map +1 -1
- package/dist/cli/commands/update.d.ts +6 -0
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/commands/vendor.d.ts +5 -0
- package/dist/cli/commands/vendor.d.ts.map +1 -1
- package/dist/cli/conflict-check.d.ts +6 -0
- package/dist/cli/conflict-check.d.ts.map +1 -1
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/components.d.ts.map +1 -1
- package/dist/cli/handlers/dev.d.ts.map +1 -1
- package/dist/cli/handlers/fan-out.d.ts.map +1 -1
- package/dist/cli/handlers/init.d.ts.map +1 -1
- package/dist/cli/handlers/lifecycle.d.ts.map +1 -1
- package/dist/cli/handlers/misc.d.ts.map +1 -1
- package/dist/cli/handlers/operator.d.ts +7 -0
- package/dist/cli/handlers/operator.d.ts.map +1 -1
- package/dist/cli/handlers/promote.d.ts +20 -0
- package/dist/cli/handlers/promote.d.ts.map +1 -0
- package/dist/cli/handlers/run-generate.d.ts +39 -0
- package/dist/cli/handlers/run-generate.d.ts.map +1 -0
- package/dist/cli/handlers/run.d.ts +4 -1
- package/dist/cli/handlers/run.d.ts.map +1 -1
- package/dist/cli/handlers/vendor.d.ts +8 -3
- package/dist/cli/handlers/vendor.d.ts.map +1 -1
- package/dist/cli/main.d.ts +12 -0
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/mcp/op-tools.d.ts.map +1 -1
- package/dist/cli/plugins.d.ts +14 -0
- package/dist/cli/plugins.d.ts.map +1 -1
- package/dist/cli/registry.d.ts +46 -1
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/codegen/fetch.d.ts +10 -0
- package/dist/codegen/fetch.d.ts.map +1 -1
- package/dist/components/capability-plugin-loader.d.ts.map +1 -1
- package/dist/components/cli-support.d.ts +3 -1
- package/dist/components/cli-support.d.ts.map +1 -1
- package/dist/components/discover.d.ts.map +1 -1
- package/dist/components/driver.d.ts +16 -2
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/fan-out-support.d.ts.map +1 -1
- package/dist/components/gate-plan.d.ts +40 -0
- package/dist/components/gate-plan.d.ts.map +1 -0
- package/dist/components/pilots/alb-ecs.pilot.d.ts +7 -1
- package/dist/components/pilots/alb-ecs.pilot.d.ts.map +1 -1
- package/dist/components/presets/ecs-fargate.d.ts +10 -4
- package/dist/components/presets/ecs-fargate.d.ts.map +1 -1
- package/dist/components/promote.d.ts +264 -0
- package/dist/components/promote.d.ts.map +1 -0
- package/dist/components/sandbox/driver.d.ts.map +1 -1
- package/dist/components/sandbox/run.d.ts.map +1 -1
- package/dist/components/verbs/build-archive.d.ts +22 -11
- package/dist/components/verbs/build-archive.d.ts.map +1 -1
- package/dist/components/verbs/run-agent.d.ts.map +1 -1
- package/dist/config-static.d.ts +59 -0
- package/dist/config-static.d.ts.map +1 -0
- package/dist/config.d.ts +104 -5
- package/dist/config.d.ts.map +1 -1
- package/dist/content-digest.d.ts +17 -0
- package/dist/content-digest.d.ts.map +1 -0
- package/dist/discovery/files.d.ts +48 -4
- package/dist/discovery/files.d.ts.map +1 -1
- package/dist/discovery/fold-import.d.ts +32 -1
- package/dist/discovery/fold-import.d.ts.map +1 -1
- package/dist/discovery/index.d.ts.map +1 -1
- package/dist/discovery/sandbox/driver.d.ts +20 -0
- package/dist/discovery/sandbox/driver.d.ts.map +1 -1
- package/dist/discovery/sandbox/fork.d.ts +20 -0
- package/dist/discovery/sandbox/fork.d.ts.map +1 -1
- package/dist/discovery/walk.d.ts +119 -0
- package/dist/discovery/walk.d.ts.map +1 -0
- package/dist/graph-ir.d.ts +17 -1
- package/dist/graph-ir.d.ts.map +1 -1
- package/dist/join-key.d.ts +31 -0
- package/dist/join-key.d.ts.map +1 -0
- package/dist/lexicon-module.d.ts +110 -0
- package/dist/lexicon-module.d.ts.map +1 -0
- package/dist/lexicon.d.ts +82 -1
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/lifecycle/build-ledger-store.d.ts.map +1 -1
- package/dist/lifecycle/digest.d.ts +5 -1
- package/dist/lifecycle/digest.d.ts.map +1 -1
- package/dist/lifecycle/gate-ledger.d.ts +20 -5
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
- package/dist/lifecycle/git.d.ts +64 -0
- package/dist/lifecycle/git.d.ts.map +1 -1
- package/dist/lifecycle/lease.d.ts +8 -1
- package/dist/lifecycle/lease.d.ts.map +1 -1
- package/dist/lifecycle/legacy-digest.d.ts +59 -0
- package/dist/lifecycle/legacy-digest.d.ts.map +1 -0
- package/dist/lifecycle/member-ledger.d.ts +67 -0
- package/dist/lifecycle/member-ledger.d.ts.map +1 -0
- package/dist/lifecycle/plan-digest.d.ts +4 -3
- package/dist/lifecycle/plan-digest.d.ts.map +1 -1
- package/dist/lifecycle/release-ledger.d.ts +42 -1
- package/dist/lifecycle/release-ledger.d.ts.map +1 -1
- package/dist/lifecycle/status.d.ts +90 -5
- package/dist/lifecycle/status.d.ts.map +1 -1
- package/dist/lint/rules/comp/comp003-mutating-no-rollback.d.ts +2 -3
- package/dist/lint/rules/comp/comp003-mutating-no-rollback.d.ts.map +1 -1
- package/dist/op/activities/activity-contracts.d.ts +32 -0
- package/dist/op/activities/activity-contracts.d.ts.map +1 -1
- package/dist/op/activities/index.d.ts +2 -0
- package/dist/op/activities/index.d.ts.map +1 -1
- package/dist/op/activities/propose-upgrade.d.ts +75 -0
- package/dist/op/activities/propose-upgrade.d.ts.map +1 -0
- package/dist/op/activity-contract-registry.d.ts.map +1 -1
- package/dist/op/activity-registry.d.ts.map +1 -1
- package/dist/op/discover.d.ts.map +1 -1
- package/dist/op/gate-approval.d.ts.map +1 -1
- package/dist/op/gate-name.d.ts +7 -0
- package/dist/op/gate-name.d.ts.map +1 -1
- package/dist/op/gate-summary.d.ts +16 -0
- package/dist/op/gate-summary.d.ts.map +1 -1
- package/dist/op/gate.d.ts +16 -2
- package/dist/op/gate.d.ts.map +1 -1
- package/dist/op/generate-pipeline.d.ts.map +1 -1
- package/dist/op/runtimes/local.d.ts.map +1 -1
- package/dist/project-root.d.ts +26 -0
- package/dist/project-root.d.ts.map +1 -1
- package/dist/workspace/__fixtures__/contract-repo.d.ts +37 -0
- package/dist/workspace/__fixtures__/contract-repo.d.ts.map +1 -0
- package/dist/workspace/__fixtures__/two-member-workspace.d.ts +11 -0
- package/dist/workspace/__fixtures__/two-member-workspace.d.ts.map +1 -0
- package/dist/workspace/checks/generated.d.ts +156 -0
- package/dist/workspace/checks/generated.d.ts.map +1 -0
- package/dist/workspace/checks/ledgers.d.ts +78 -0
- package/dist/workspace/checks/ledgers.d.ts.map +1 -0
- package/dist/workspace/checks/links.d.ts +25 -0
- package/dist/workspace/checks/links.d.ts.map +1 -0
- package/dist/workspace/checks/pipelines.d.ts +76 -0
- package/dist/workspace/checks/pipelines.d.ts.map +1 -0
- package/dist/workspace/checks.d.ts +161 -0
- package/dist/workspace/checks.d.ts.map +1 -0
- package/dist/workspace/compose-graph.d.ts +115 -0
- package/dist/workspace/compose-graph.d.ts.map +1 -0
- package/dist/workspace/compose-reports.d.ts +68 -0
- package/dist/workspace/compose-reports.d.ts.map +1 -0
- package/dist/workspace/declaration.d.ts +220 -0
- package/dist/workspace/declaration.d.ts.map +1 -0
- package/dist/workspace/declaration.schema.json +434 -0
- package/dist/workspace/generated-files.d.ts +65 -0
- package/dist/workspace/generated-files.d.ts.map +1 -0
- package/dist/workspace/glob.d.ts +13 -0
- package/dist/workspace/glob.d.ts.map +1 -0
- package/dist/workspace/graph-cli.d.ts +75 -0
- package/dist/workspace/graph-cli.d.ts.map +1 -0
- package/dist/workspace/init.d.ts +96 -0
- package/dist/workspace/init.d.ts.map +1 -0
- package/dist/workspace/jsonc.d.ts +38 -0
- package/dist/workspace/jsonc.d.ts.map +1 -0
- package/dist/workspace/kinds.d.ts +192 -0
- package/dist/workspace/kinds.d.ts.map +1 -0
- package/dist/workspace/lineage-check.d.ts +84 -0
- package/dist/workspace/lineage-check.d.ts.map +1 -0
- package/dist/workspace/lineage-cli.d.ts +31 -0
- package/dist/workspace/lineage-cli.d.ts.map +1 -0
- package/dist/workspace/lineage-init.d.ts +101 -0
- package/dist/workspace/lineage-init.d.ts.map +1 -0
- package/dist/workspace/lineage-lock.d.ts +258 -0
- package/dist/workspace/lineage-lock.d.ts.map +1 -0
- package/dist/workspace/lineage-merge.d.ts +14 -0
- package/dist/workspace/lineage-merge.d.ts.map +1 -0
- package/dist/workspace/lineage-migrations.d.ts +178 -0
- package/dist/workspace/lineage-migrations.d.ts.map +1 -0
- package/dist/workspace/lineage-update.d.ts +59 -0
- package/dist/workspace/lineage-update.d.ts.map +1 -0
- package/dist/workspace/lineage-upgrade-cli.d.ts +40 -0
- package/dist/workspace/lineage-upgrade-cli.d.ts.map +1 -0
- package/dist/workspace/lineage-upgrade.d.ts +146 -0
- package/dist/workspace/lineage-upgrade.d.ts.map +1 -0
- package/dist/workspace/lineage-vendor.d.ts +63 -0
- package/dist/workspace/lineage-vendor.d.ts.map +1 -0
- package/dist/workspace/lineage-version.d.ts +32 -0
- package/dist/workspace/lineage-version.d.ts.map +1 -0
- package/dist/workspace/links.d.ts +150 -0
- package/dist/workspace/links.d.ts.map +1 -0
- package/dist/workspace/ls.d.ts +99 -0
- package/dist/workspace/ls.d.ts.map +1 -0
- package/dist/workspace/member-commands.d.ts +139 -0
- package/dist/workspace/member-commands.d.ts.map +1 -0
- package/dist/workspace/member-handles.d.ts +54 -0
- package/dist/workspace/member-handles.d.ts.map +1 -0
- package/dist/workspace/member-pipeline.d.ts +143 -0
- package/dist/workspace/member-pipeline.d.ts.map +1 -0
- package/dist/workspace/member-run.d.ts +67 -0
- package/dist/workspace/member-run.d.ts.map +1 -0
- package/dist/workspace/reason-codes.d.ts +65 -0
- package/dist/workspace/reason-codes.d.ts.map +1 -0
- package/dist/workspace/record-source.d.ts +22 -0
- package/dist/workspace/record-source.d.ts.map +1 -0
- package/dist/workspace/records-cli.d.ts +81 -0
- package/dist/workspace/records-cli.d.ts.map +1 -0
- package/dist/workspace/records.d.ts +118 -0
- package/dist/workspace/records.d.ts.map +1 -0
- package/dist/workspace/root-refusal.d.ts +53 -0
- package/dist/workspace/root-refusal.d.ts.map +1 -0
- package/dist/workspace/status.d.ts +150 -0
- package/dist/workspace/status.d.ts.map +1 -0
- package/dist/workspace/template-manifest.d.ts +90 -0
- package/dist/workspace/template-manifest.d.ts.map +1 -0
- package/dist/workspace/tree.d.ts +36 -0
- package/dist/workspace/tree.d.ts.map +1 -0
- package/dist/workspace/trust/attestor.d.ts +67 -0
- package/dist/workspace/trust/attestor.d.ts.map +1 -0
- package/dist/workspace/trust/policy.d.ts +111 -0
- package/dist/workspace/trust/policy.d.ts.map +1 -0
- package/dist/workspace/trust/provenance.d.ts +67 -0
- package/dist/workspace/trust/provenance.d.ts.map +1 -0
- package/dist/workspace/trust/ssh-commit.d.ts +43 -0
- package/dist/workspace/trust/ssh-commit.d.ts.map +1 -0
- package/dist/workspace/trust/test-repo.d.ts +42 -0
- package/dist/workspace/trust/test-repo.d.ts.map +1 -0
- package/dist/workspace/trust/verify-cli.d.ts +9 -0
- package/dist/workspace/trust/verify-cli.d.ts.map +1 -0
- package/dist/workspace/trust/verify.d.ts +66 -0
- package/dist/workspace/trust/verify.d.ts.map +1 -0
- package/dist/workspace/which-chant.d.ts +58 -0
- package/dist/workspace/which-chant.d.ts.map +1 -0
- package/dist/workspace/workspace-kinds.schema.json +133 -0
- package/package.json +4 -3
- package/src/audit/core.ts +13 -2
- package/src/audit/discover.ts +102 -36
- package/src/audit/report-html.ts +3 -1
- package/src/audit/report-model.ts +14 -1
- package/src/audit/terraform-state.test.ts +81 -1
- package/src/audit/terraform-state.ts +25 -0
- package/src/cli/command-group.ts +7 -0
- package/src/cli/commands/audit-truncation.test.ts +167 -0
- package/src/cli/commands/audit.ts +132 -29
- package/src/cli/commands/check-lexicon-examples.ts +2 -1
- package/src/cli/commands/check-lexicon.ts +24 -0
- package/src/cli/commands/doctor.test.ts +30 -0
- package/src/cli/commands/doctor.ts +21 -0
- package/src/cli/commands/import-agents.ts +15 -4
- package/src/cli/commands/init.ts +76 -25
- package/src/cli/commands/lint.test.ts +52 -1
- package/src/cli/commands/lint.ts +41 -71
- package/src/cli/commands/onboard.ts +15 -0
- package/src/cli/commands/update.ts +18 -5
- package/src/cli/commands/vendor.ts +11 -6
- package/src/cli/conflict-check.test.ts +18 -1
- package/src/cli/conflict-check.ts +13 -0
- package/src/cli/discovery-skip.test.ts +168 -0
- package/src/cli/handlers/__snapshots__/build-member.test.ts.snap +38 -0
- package/src/cli/handlers/build-member.test.ts +127 -0
- package/src/cli/handlers/build.test.ts +11 -0
- package/src/cli/handlers/build.ts +35 -1
- package/src/cli/handlers/components.test.ts +127 -0
- package/src/cli/handlers/components.ts +70 -8
- package/src/cli/handlers/dev.ts +6 -1
- package/src/cli/handlers/fan-out.ts +9 -2
- package/src/cli/handlers/graph.test.ts +20 -0
- package/src/cli/handlers/graph.ts +4 -2
- package/src/cli/handlers/init.ts +54 -1
- package/src/cli/handlers/lifecycle.ts +2 -1
- package/src/cli/handlers/misc.ts +16 -0
- package/src/cli/handlers/operator.test.ts +68 -0
- package/src/cli/handlers/operator.ts +39 -10
- package/src/cli/handlers/promote.test.ts +377 -0
- package/src/cli/handlers/promote.ts +391 -0
- package/src/cli/handlers/run-generate-member.test.ts +83 -0
- package/src/cli/handlers/run-generate.test.ts +158 -0
- package/src/cli/handlers/run-generate.ts +168 -0
- package/src/cli/handlers/run.test.ts +47 -0
- package/src/cli/handlers/run.ts +41 -6
- package/src/cli/handlers/vendor.ts +147 -43
- package/src/cli/main.test.ts +137 -1
- package/src/cli/main.ts +290 -24
- package/src/cli/mcp/op-tools.ts +2 -1
- package/src/cli/path-lexicon-messages.test.ts +152 -0
- package/src/cli/plugins.ts +43 -5
- package/src/cli/registry.ts +46 -1
- package/src/cli/static-config-read.test.ts +208 -0
- package/src/codegen/fetch.test.ts +63 -1
- package/src/codegen/fetch.ts +30 -1
- package/src/components/__fixtures__/alb-ecs-service.json +0 -8
- package/src/components/capability-plugin-loader.ts +3 -1
- package/src/components/cli-support.ts +9 -3
- package/src/components/discover.test.ts +27 -57
- package/src/components/discover.ts +20 -51
- package/src/components/driver.test.ts +90 -12
- package/src/components/driver.ts +43 -5
- package/src/components/fan-out-support.ts +2 -1
- package/src/components/gate-plan.ts +53 -0
- package/src/components/pilots/README.md +1 -1
- package/src/components/pilots/alb-ecs.pilot.ts +7 -7
- package/src/components/presets/ecs-fargate.ts +10 -5
- package/src/components/promote.test.ts +645 -0
- package/src/components/promote.ts +641 -0
- package/src/components/sandbox/driver.ts +8 -8
- package/src/components/sandbox/run.ts +4 -1
- package/src/components/verbs/build-archive.ts +27 -21
- package/src/components/verbs/run-agent.ts +3 -5
- package/src/config-static.test.ts +136 -0
- package/src/config-static.ts +232 -0
- package/src/config.test.ts +40 -0
- package/src/config.ts +161 -11
- package/src/content-digest.test.ts +120 -0
- package/src/content-digest.ts +21 -0
- package/src/discovery/files.test.ts +127 -1
- package/src/discovery/files.ts +91 -59
- package/src/discovery/fold-import.ts +127 -9
- package/src/discovery/index.ts +1 -0
- package/src/discovery/sandbox/driver.ts +73 -35
- package/src/discovery/sandbox/fork-diagnostic.test.ts +136 -13
- package/src/discovery/sandbox/fork.ts +83 -43
- package/src/discovery/sandbox/path-lexicon-multifile.test.ts +285 -0
- package/src/discovery/sandbox/path-lexicon-parity.test.ts +162 -0
- package/src/discovery/walk.test.ts +263 -0
- package/src/discovery/walk.ts +334 -0
- package/src/effect-receipt.ts +2 -2
- package/src/graph-ir.ts +18 -1
- package/src/join-key.test.ts +25 -0
- package/src/join-key.ts +39 -0
- package/src/lexicon-module.test.ts +203 -0
- package/src/lexicon-module.ts +215 -0
- package/src/lexicon.ts +105 -1
- package/src/lifecycle/build-ledger-store.ts +13 -2
- package/src/lifecycle/digest.ts +9 -5
- package/src/lifecycle/gate-ledger.test.ts +20 -0
- package/src/lifecycle/gate-ledger.ts +28 -6
- package/src/lifecycle/git.test.ts +13 -1
- package/src/lifecycle/git.ts +221 -176
- package/src/lifecycle/lease.ts +25 -10
- package/src/lifecycle/legacy-digest.test.ts +206 -0
- package/src/lifecycle/legacy-digest.ts +103 -0
- package/src/lifecycle/member-ledger.test.ts +319 -0
- package/src/lifecycle/member-ledger.ts +145 -0
- package/src/lifecycle/plan-digest.ts +7 -7
- package/src/lifecycle/release-ledger.test.ts +20 -0
- package/src/lifecycle/release-ledger.ts +53 -3
- package/src/lifecycle/status.test.ts +151 -1
- package/src/lifecycle/status.ts +228 -7
- package/src/lint/rules/comp/comp003-mutating-no-rollback.ts +2 -3
- package/src/op/activities/activity-contracts.ts +37 -0
- package/src/op/activities/index.ts +10 -0
- package/src/op/activities/propose-upgrade.ts +206 -0
- package/src/op/activity-contract-registry.ts +18 -4
- package/src/op/activity-registry.ts +26 -0
- package/src/op/discover.test.ts +14 -4
- package/src/op/discover.ts +19 -23
- package/src/op/gate-approval.ts +3 -1
- package/src/op/gate-name.ts +8 -0
- package/src/op/gate-summary.test.ts +14 -0
- package/src/op/gate-summary.ts +25 -2
- package/src/op/gate.ts +36 -7
- package/src/op/generate-pipeline.test.ts +14 -5
- package/src/op/generate-pipeline.ts +2 -1
- package/src/op/runtimes/local.ts +2 -1
- package/src/project-root.test.ts +66 -1
- package/src/project-root.ts +48 -0
- package/src/workspace/__fixtures__/contract-repo.ts +100 -0
- package/src/workspace/__fixtures__/two-member-workspace.ts +35 -0
- package/src/workspace/behold-kinds.test.ts +162 -0
- package/src/workspace/check-contract.test.ts +127 -0
- package/src/workspace/check.schema.json +347 -0
- package/src/workspace/checks/generated.test.ts +287 -0
- package/src/workspace/checks/generated.ts +475 -0
- package/src/workspace/checks/ledgers.test.ts +139 -0
- package/src/workspace/checks/ledgers.ts +246 -0
- package/src/workspace/checks/links.ts +183 -0
- package/src/workspace/checks/pipelines.test.ts +133 -0
- package/src/workspace/checks/pipelines.ts +225 -0
- package/src/workspace/checks-repo.test.ts +71 -0
- package/src/workspace/checks.test.ts +450 -0
- package/src/workspace/checks.ts +461 -0
- package/src/workspace/compose-graph.test.ts +146 -0
- package/src/workspace/compose-graph.ts +228 -0
- package/src/workspace/compose-reports.test.ts +109 -0
- package/src/workspace/compose-reports.ts +186 -0
- package/src/workspace/declaration.schema.json +434 -0
- package/src/workspace/declaration.test.ts +347 -0
- package/src/workspace/declaration.ts +623 -0
- package/src/workspace/generated-files.test.ts +114 -0
- package/src/workspace/generated-files.ts +94 -0
- package/src/workspace/glob.ts +49 -0
- package/src/workspace/graph-cli.ts +220 -0
- package/src/workspace/graph-contract.test.ts +204 -0
- package/src/workspace/graph.schema.json +662 -0
- package/src/workspace/init.test.ts +223 -0
- package/src/workspace/init.ts +585 -0
- package/src/workspace/jsonc.test.ts +65 -0
- package/src/workspace/jsonc.ts +231 -0
- package/src/workspace/kinds.test.ts +288 -0
- package/src/workspace/kinds.ts +506 -0
- package/src/workspace/lineage-check.ts +264 -0
- package/src/workspace/lineage-cli.ts +114 -0
- package/src/workspace/lineage-init.test.ts +231 -0
- package/src/workspace/lineage-init.ts +365 -0
- package/src/workspace/lineage-lock.test.ts +224 -0
- package/src/workspace/lineage-lock.ts +357 -0
- package/src/workspace/lineage-merge.ts +44 -0
- package/src/workspace/lineage-migrations.test.ts +178 -0
- package/src/workspace/lineage-migrations.ts +343 -0
- package/src/workspace/lineage-update.ts +160 -0
- package/src/workspace/lineage-upgrade-cli.ts +151 -0
- package/src/workspace/lineage-upgrade.test.ts +474 -0
- package/src/workspace/lineage-upgrade.ts +624 -0
- package/src/workspace/lineage-vendor.test.ts +126 -0
- package/src/workspace/lineage-vendor.ts +215 -0
- package/src/workspace/lineage-version.ts +127 -0
- package/src/workspace/links.test.ts +344 -0
- package/src/workspace/links.ts +331 -0
- package/src/workspace/ls-contract.test.ts +200 -0
- package/src/workspace/ls.schema.json +190 -0
- package/src/workspace/ls.ts +254 -0
- package/src/workspace/member-commands.e2e.test.ts +244 -0
- package/src/workspace/member-commands.test.ts +217 -0
- package/src/workspace/member-commands.ts +540 -0
- package/src/workspace/member-handles.test.ts +76 -0
- package/src/workspace/member-handles.ts +228 -0
- package/src/workspace/member-pipeline.test.ts +135 -0
- package/src/workspace/member-pipeline.ts +317 -0
- package/src/workspace/member-run.ts +146 -0
- package/src/workspace/read-contract.test.ts +129 -0
- package/src/workspace/reason-codes.test.ts +113 -0
- package/src/workspace/reason-codes.ts +81 -0
- package/src/workspace/record-source.ts +117 -0
- package/src/workspace/records-cli.ts +198 -0
- package/src/workspace/records-contract.test.ts +93 -0
- package/src/workspace/records.schema.json +150 -0
- package/src/workspace/records.test.ts +243 -0
- package/src/workspace/records.ts +384 -0
- package/src/workspace/root-refusal.ts +97 -0
- package/src/workspace/status-contract.test.ts +308 -0
- package/src/workspace/status.schema.json +210 -0
- package/src/workspace/status.ts +412 -0
- package/src/workspace/template-manifest.test.ts +79 -0
- package/src/workspace/template-manifest.ts +221 -0
- package/src/workspace/tree.ts +132 -0
- package/src/workspace/trust/attestor.ts +93 -0
- package/src/workspace/trust/policy.ts +306 -0
- package/src/workspace/trust/provenance.ts +181 -0
- package/src/workspace/trust/ssh-commit.ts +138 -0
- package/src/workspace/trust/test-repo.ts +138 -0
- package/src/workspace/trust/trust.test.ts +397 -0
- package/src/workspace/trust/verify-cli.ts +56 -0
- package/src/workspace/trust/verify.ts +194 -0
- package/src/workspace/which-chant.test.ts +117 -0
- package/src/workspace/which-chant.ts +151 -0
- package/src/workspace/workspace-kinds.schema.json +133 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `chant workspace records --kind <path> [--current] [--at <rev>] [--base <rev>]
|
|
3
|
+
* [--require attested] [--json]`, the first-test slice of the records query
|
|
4
|
+
* (#2546, #2536), with each record's provenance level (#2547).
|
|
5
|
+
*
|
|
6
|
+
* It reads every record the kind file locates and prints them, with reason
|
|
7
|
+
* codes for any that are invalid. An invalid record never fails the command:
|
|
8
|
+
* the exit code is 0 whenever the read itself worked. Only a kind, schema or
|
|
9
|
+
* revision that cannot be read exits 1.
|
|
10
|
+
*
|
|
11
|
+
* It needs no `chant.workspace.json`. The kind is passed explicitly, so
|
|
12
|
+
* nothing is inferred (#2525 rule 1).
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { realpathSync } from "node:fs";
|
|
16
|
+
import { relative } from "node:path";
|
|
17
|
+
import { formatError } from "../cli/format";
|
|
18
|
+
import type { CommandContext } from "../cli/registry";
|
|
19
|
+
import { gitRevisionSource, gitRoot, resolveRevision, workingTreeSource } from "./record-source";
|
|
20
|
+
import { loadRecordKind, readRecords, RecordReadError, type ReadErrorCode, type RecordEntry } from "./records";
|
|
21
|
+
import { activeAttestors, type ProvenanceLevel } from "./trust/attestor";
|
|
22
|
+
import { policyAtBase, recordProvenance, resolveBase, type BaseSource, type RecordProvenance } from "./trust/provenance";
|
|
23
|
+
|
|
24
|
+
/** The version of the `records` output this chant writes. */
|
|
25
|
+
export const RECORDS_CONTRACT_VERSION = 1;
|
|
26
|
+
|
|
27
|
+
/** `$id` of the JSON Schema for the `--json` output, shipped beside this file. */
|
|
28
|
+
export const RECORDS_OUTPUT_SCHEMA_ID = "https://intentius.io/chant/schemas/workspace/records/v1/records.schema.json";
|
|
29
|
+
|
|
30
|
+
const USAGE = "chant workspace records --kind <kind file> [--current] [--at <rev>] [--base <rev>] [--require attested] [--json]";
|
|
31
|
+
|
|
32
|
+
/** Exit code when the read worked and a record falls below `--require`. */
|
|
33
|
+
export const EXIT_BELOW_REQUIRED = 2;
|
|
34
|
+
|
|
35
|
+
export interface RecordsQuery {
|
|
36
|
+
kind: string;
|
|
37
|
+
current?: boolean;
|
|
38
|
+
at?: string;
|
|
39
|
+
/** The revision the trust policy is read at (#2547). Defaults to the target branch tip. */
|
|
40
|
+
base?: string;
|
|
41
|
+
/** Where `kind` is resolved from and the repository is found. */
|
|
42
|
+
cwd: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** A record as the output carries it: the entry plus its provenance (#2547). */
|
|
46
|
+
export type RecordView = RecordEntry & { provenance: RecordProvenance };
|
|
47
|
+
|
|
48
|
+
/** Where provenance was judged from (#2547). */
|
|
49
|
+
export interface TrustView {
|
|
50
|
+
/** The full commit id the policy was read at, or null when there is no base. */
|
|
51
|
+
base: string | null;
|
|
52
|
+
baseFrom: BaseSource | null;
|
|
53
|
+
/** Whether a signers file exists at base. False means every record is `unattested`. */
|
|
54
|
+
active: boolean;
|
|
55
|
+
signersPath: string;
|
|
56
|
+
problems: string[];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** The `records` output: a result, or a failure with one error code. */
|
|
60
|
+
export type RecordsDocument =
|
|
61
|
+
| {
|
|
62
|
+
$schema: string;
|
|
63
|
+
contract: number;
|
|
64
|
+
kind: { name: string; schema: string; file: string };
|
|
65
|
+
at: string | null;
|
|
66
|
+
current: boolean;
|
|
67
|
+
trust: TrustView;
|
|
68
|
+
records: RecordView[];
|
|
69
|
+
summary: { total: number; valid: number; invalid: number; superseded: number };
|
|
70
|
+
}
|
|
71
|
+
| { $schema: string; contract: number; error: { code: ReadErrorCode; message: string } };
|
|
72
|
+
|
|
73
|
+
/** Run the query and build the document `--json` prints. Never throws a {@link RecordReadError}. */
|
|
74
|
+
export async function queryRecords(query: RecordsQuery): Promise<RecordsDocument> {
|
|
75
|
+
// git reports its top through symlinks resolved (/var is /private/var on
|
|
76
|
+
// macOS), so the directory has to be too, or record paths leave the repository.
|
|
77
|
+
const cwd = realpathOr(query.cwd);
|
|
78
|
+
const top = gitRoot(cwd);
|
|
79
|
+
const root = top ?? cwd;
|
|
80
|
+
try {
|
|
81
|
+
const loaded = await loadRecordKind(query.kind, cwd);
|
|
82
|
+
let at: string | null = null;
|
|
83
|
+
let source = workingTreeSource(root);
|
|
84
|
+
if (query.at !== undefined) {
|
|
85
|
+
if (!top) throw new RecordReadError("not-a-git-repository", "--at reads git objects, and this directory is not in a git repository");
|
|
86
|
+
at = resolveRevision(top, query.at);
|
|
87
|
+
source = gitRevisionSource(top, at);
|
|
88
|
+
}
|
|
89
|
+
const result = await readRecords(loaded, { root, source, current: !!query.current });
|
|
90
|
+
// Provenance, judged by the policy at base and never by the tree read (#2547).
|
|
91
|
+
const base = top ? resolveBase(top, query.base) : { commit: null, from: null };
|
|
92
|
+
const policy = top ? policyAtBase(top, base) : policyAtBase(root, base);
|
|
93
|
+
const provenance = recordProvenance({
|
|
94
|
+
repo: top,
|
|
95
|
+
policy,
|
|
96
|
+
at,
|
|
97
|
+
paths: result.records.map((r) => r.path),
|
|
98
|
+
attestors: policy.active ? await activeAttestors() : [],
|
|
99
|
+
});
|
|
100
|
+
return {
|
|
101
|
+
$schema: RECORDS_OUTPUT_SCHEMA_ID,
|
|
102
|
+
contract: RECORDS_CONTRACT_VERSION,
|
|
103
|
+
kind: {
|
|
104
|
+
name: loaded.kind.name,
|
|
105
|
+
schema: loaded.kind.schema.id,
|
|
106
|
+
file: relative(root, loaded.file).split("\\").join("/"),
|
|
107
|
+
},
|
|
108
|
+
at,
|
|
109
|
+
current: !!query.current,
|
|
110
|
+
trust: { base: base.commit, baseFrom: base.from, active: policy.active, signersPath: policy.signersPath, problems: policy.problems },
|
|
111
|
+
records: result.records.map((r) => ({ ...r, provenance: provenance.get(r.path)! })),
|
|
112
|
+
summary: result.summary,
|
|
113
|
+
};
|
|
114
|
+
} catch (err) {
|
|
115
|
+
if (!(err instanceof RecordReadError)) throw err;
|
|
116
|
+
return { $schema: RECORDS_OUTPUT_SCHEMA_ID, contract: RECORDS_CONTRACT_VERSION, error: { code: err.code, message: err.message } };
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export async function runWorkspaceRecords(ctx: CommandContext): Promise<number> {
|
|
121
|
+
const { args } = ctx;
|
|
122
|
+
if (!args.kind) {
|
|
123
|
+
console.error(formatError({ message: "--kind <kind file> is required", hint: USAGE }));
|
|
124
|
+
return 1;
|
|
125
|
+
}
|
|
126
|
+
if (args.require !== undefined && args.require !== "attested") {
|
|
127
|
+
console.error(formatError({ message: `--require takes one level, attested, not ${JSON.stringify(args.require)}`, hint: USAGE }));
|
|
128
|
+
return 1;
|
|
129
|
+
}
|
|
130
|
+
const doc = await queryRecords({ kind: args.kind, current: args.current, at: args.at, base: args.base, cwd: process.cwd() });
|
|
131
|
+
if (args.json) {
|
|
132
|
+
console.log(JSON.stringify(doc, null, 2));
|
|
133
|
+
} else if ("error" in doc) {
|
|
134
|
+
console.error(formatError({ message: `${doc.error.code}: ${doc.error.message}`, hint: USAGE }));
|
|
135
|
+
} else {
|
|
136
|
+
console.log(formatRecords(doc.records, doc.summary, doc.at));
|
|
137
|
+
}
|
|
138
|
+
if ("error" in doc) return 1;
|
|
139
|
+
if (args.require) {
|
|
140
|
+
const below = belowRequired(doc.records, args.require);
|
|
141
|
+
if (below.length > 0) {
|
|
142
|
+
console.error(
|
|
143
|
+
formatError({
|
|
144
|
+
message: `${below.length} of ${doc.records.length} records are not ${args.require}: ${below
|
|
145
|
+
.slice(0, 5)
|
|
146
|
+
.map((r) => `${r.path} (${r.provenance.level})`)
|
|
147
|
+
.join(", ")}${below.length > 5 ? ", ..." : ""}`,
|
|
148
|
+
hint: doc.trust.active ? "run with --json to see each record's reason" : `there is no signers file (${doc.trust.signersPath}) at base`,
|
|
149
|
+
}),
|
|
150
|
+
);
|
|
151
|
+
return EXIT_BELOW_REQUIRED;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return 0;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function realpathOr(dir: string): string {
|
|
158
|
+
try {
|
|
159
|
+
return realpathSync(dir);
|
|
160
|
+
} catch {
|
|
161
|
+
return dir;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/** Records whose provenance falls below `required`. Only `attested` can be required. */
|
|
166
|
+
export function belowRequired(records: RecordView[], required: ProvenanceLevel): RecordView[] {
|
|
167
|
+
return records.filter((r) => r.provenance.level !== required);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function formatRecords(records: RecordView[], summary: { total: number; valid: number; invalid: number; superseded: number }, at: string | null): string {
|
|
171
|
+
const lines: string[] = [];
|
|
172
|
+
const idWidth = Math.max(2, ...records.map((r) => (r.id ?? "-").length));
|
|
173
|
+
const stateWidth = Math.max(5, ...records.map((r) => (r.state ?? "-").length));
|
|
174
|
+
for (const r of records) {
|
|
175
|
+
const title = typeof r.data?.title === "string" ? r.data.title : r.path;
|
|
176
|
+
const flag = r.valid ? "" : " INVALID";
|
|
177
|
+
const superseded = r.supersededBy ? ` superseded by ${r.supersededBy}` : "";
|
|
178
|
+
const attested = r.provenance.level === "attested" ? ` attested by ${r.provenance.principal}` : "";
|
|
179
|
+
lines.push(`${(r.id ?? "-").padEnd(idWidth)} ${(r.state ?? "-").padEnd(stateWidth)} ${title}${superseded}${attested}${flag}`);
|
|
180
|
+
for (const reason of r.reasons) lines.push(`${" ".repeat(idWidth + 2)}${reason.code}: ${reason.message} (${r.path})`);
|
|
181
|
+
}
|
|
182
|
+
lines.push(
|
|
183
|
+
`${summary.total} records${at ? ` at ${at.slice(0, 8)}` : ""}: ${summary.valid} valid, ${summary.invalid} invalid, ${summary.superseded} superseded`,
|
|
184
|
+
);
|
|
185
|
+
return lines.join("\n");
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/** `chant workspace <anything else>`. */
|
|
189
|
+
export async function runWorkspaceUnknown(ctx: CommandContext): Promise<number> {
|
|
190
|
+
const sub = ctx.args.path && ctx.args.path !== "." ? ctx.args.path : "";
|
|
191
|
+
console.error(
|
|
192
|
+
formatError({
|
|
193
|
+
message: sub ? `Unknown workspace subcommand: ${sub}` : "chant workspace needs a subcommand",
|
|
194
|
+
hint: `Workspace subcommands: audit, build, check, graph, init, lineage, lint, ls, records, status, upgrade, verify. Run "chant --help" for their options.`,
|
|
195
|
+
}),
|
|
196
|
+
);
|
|
197
|
+
return 1;
|
|
198
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The read contract for `chant workspace records --json` (#2536): the output
|
|
3
|
+
* schema is a valid draft 2020-12 document, its closed code lists match the
|
|
4
|
+
* code, and real output validates against it. The reference workspace (#2543)
|
|
5
|
+
* doesn't exist yet, so the chant repo's own decision files stand in for it.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { cpSync, mkdirSync, mkdtempSync, realpathSync, rmSync, writeFileSync } from "node:fs";
|
|
9
|
+
import { tmpdir } from "node:os";
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
import Ajv2020 from "ajv/dist/2020";
|
|
12
|
+
import { afterAll, describe, expect, test } from "vitest";
|
|
13
|
+
import { queryRecords, RECORDS_CONTRACT_VERSION, RECORDS_OUTPUT_SCHEMA_ID, type RecordsDocument } from "./records-cli";
|
|
14
|
+
import { READ_ERROR_CODES, RECORD_REASON_CODES } from "./records";
|
|
15
|
+
import schema from "./records.schema.json";
|
|
16
|
+
import { PROVENANCE_LEVELS } from "./trust/attestor";
|
|
17
|
+
|
|
18
|
+
const REPO = join(import.meta.dirname, "..", "..", "..", "..");
|
|
19
|
+
const KIND = "docs/design/decisions/decision.kind.mjs";
|
|
20
|
+
|
|
21
|
+
const ajv = new Ajv2020({ strict: true, allErrors: true });
|
|
22
|
+
const validate = ajv.compile(schema);
|
|
23
|
+
|
|
24
|
+
function expectValid(doc: RecordsDocument): void {
|
|
25
|
+
const ok = validate(doc);
|
|
26
|
+
expect(ok, JSON.stringify(validate.errors, null, 2)).toBe(true);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const scratch: string[] = [];
|
|
30
|
+
afterAll(() => {
|
|
31
|
+
for (const d of scratch) rmSync(d, { recursive: true, force: true });
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
/** A directory holding a copy of the decisions, kind and schema, outside any git repository. */
|
|
35
|
+
function copyDecisions(): string {
|
|
36
|
+
const root = realpathSync(mkdtempSync(join(tmpdir(), "chant-records-contract-")));
|
|
37
|
+
scratch.push(root);
|
|
38
|
+
mkdirSync(join(root, "docs", "design"), { recursive: true });
|
|
39
|
+
cpSync(join(REPO, "docs", "design", "decisions"), join(root, "docs", "design", "decisions"), { recursive: true });
|
|
40
|
+
return root;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
describe("records output schema", () => {
|
|
44
|
+
test("is a valid draft 2020-12 document with the published $id", () => {
|
|
45
|
+
expect(schema.$schema).toBe("https://json-schema.org/draft/2020-12/schema");
|
|
46
|
+
expect(ajv.validateSchema(schema)).toBe(true);
|
|
47
|
+
expect(schema.$id).toBe(RECORDS_OUTPUT_SCHEMA_ID);
|
|
48
|
+
expect(RECORDS_CONTRACT_VERSION).toBe(1);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test("lists exactly the reason and error codes the code can return", () => {
|
|
52
|
+
expect(schema.$defs.reason.properties.code.enum).toEqual([...RECORD_REASON_CODES]);
|
|
53
|
+
expect(schema.$defs.failure.properties.error.properties.code.enum).toEqual([...READ_ERROR_CODES]);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test("lists exactly the provenance levels (#2547)", () => {
|
|
57
|
+
expect(schema.$defs.provenance.properties.level.enum).toEqual([...PROVENANCE_LEVELS]);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test("the chant repo's decisions validate, current and not", async () => {
|
|
61
|
+
for (const current of [false, true]) {
|
|
62
|
+
const doc = await queryRecords({ kind: KIND, current, cwd: REPO });
|
|
63
|
+
expectValid(doc);
|
|
64
|
+
expect("error" in doc).toBe(false);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test("invalid records validate, each with its reason", async () => {
|
|
69
|
+
const root = copyDecisions();
|
|
70
|
+
const dir = join(root, "docs", "design", "decisions");
|
|
71
|
+
writeFileSync(join(dir, "ws-001-trust-root.md"), "no front matter\n");
|
|
72
|
+
writeFileSync(join(dir, "ws-900-extra.md"), "---\nid: \"ws-900\"\nstate: \"decided\"\n---\n");
|
|
73
|
+
const doc = await queryRecords({ kind: KIND, cwd: root });
|
|
74
|
+
expectValid(doc);
|
|
75
|
+
if ("error" in doc) throw new Error(doc.error.message);
|
|
76
|
+
expect(doc.at).toBeNull();
|
|
77
|
+
expect(doc.summary.invalid).toBe(2);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test("every failure validates with its code", async () => {
|
|
81
|
+
const root = copyDecisions();
|
|
82
|
+
const docs = [
|
|
83
|
+
await queryRecords({ kind: "missing.kind.mjs", cwd: root }),
|
|
84
|
+
await queryRecords({ kind: KIND, at: "HEAD", cwd: root }),
|
|
85
|
+
];
|
|
86
|
+
for (const doc of docs) expectValid(doc);
|
|
87
|
+
expect(docs.map((d) => ("error" in d ? d.error.code : "ok"))).toEqual(["kind-unreadable", "not-a-git-repository"]);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test("a document mixing records and an error is refused", () => {
|
|
91
|
+
expect(validate({ $schema: RECORDS_OUTPUT_SCHEMA_ID, contract: 1, error: { code: "revision-unknown", message: "x" }, records: [] })).toBe(false);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://intentius.io/chant/schemas/workspace/records/v1/records.schema.json",
|
|
4
|
+
"title": "chant workspace records output",
|
|
5
|
+
"description": "What `chant workspace records --json` prints, version 1 of the read contract for records (#2536). This is the first-test slice (#2546): records are unsealed and there is no workspace declaration yet. Readers ignore fields they do not know; a field is only ever added within a version. The reason and error codes are closed lists: a new code is a new contract version. Contract version 1 is written by chant 0.81.0 and newer; a reader that needs it refuses output whose `contract` it doesn't know. Every code is in the one closed list of `reason-codes.ts`.",
|
|
6
|
+
"oneOf": [{ "$ref": "#/$defs/result" }, { "$ref": "#/$defs/failure" }],
|
|
7
|
+
"$defs": {
|
|
8
|
+
"result": {
|
|
9
|
+
"description": "The read worked. Exit code 0, even when some records are invalid.",
|
|
10
|
+
"type": "object",
|
|
11
|
+
"required": ["$schema", "contract", "kind", "at", "current", "records", "summary"],
|
|
12
|
+
"properties": {
|
|
13
|
+
"$schema": { "const": "https://intentius.io/chant/schemas/workspace/records/v1/records.schema.json" },
|
|
14
|
+
"contract": { "const": 1 },
|
|
15
|
+
"kind": {
|
|
16
|
+
"type": "object",
|
|
17
|
+
"required": ["name", "schema", "file"],
|
|
18
|
+
"properties": {
|
|
19
|
+
"name": { "type": "string", "description": "The kind's name, such as \"decision\"." },
|
|
20
|
+
"schema": { "type": "string", "description": "The `$id` of the schema each record was validated against." },
|
|
21
|
+
"file": { "type": "string", "description": "The kind file, relative to the repository root, with / separators." }
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"at": {
|
|
25
|
+
"description": "The full commit id the records were read at (--at), or null for the working tree.",
|
|
26
|
+
"type": ["string", "null"],
|
|
27
|
+
"pattern": "^[0-9a-f]{40,64}$"
|
|
28
|
+
},
|
|
29
|
+
"error": false,
|
|
30
|
+
"current": { "type": "boolean", "description": "Whether superseded records were left out (--current)." },
|
|
31
|
+
"trust": { "$ref": "#/$defs/trust" },
|
|
32
|
+
"records": {
|
|
33
|
+
"description": "One entry per file the kind locates, sorted by path.",
|
|
34
|
+
"type": "array",
|
|
35
|
+
"items": { "$ref": "#/$defs/record" }
|
|
36
|
+
},
|
|
37
|
+
"summary": {
|
|
38
|
+
"type": "object",
|
|
39
|
+
"required": ["total", "valid", "invalid", "superseded"],
|
|
40
|
+
"properties": {
|
|
41
|
+
"total": { "type": "integer", "minimum": 0, "description": "Entries in records." },
|
|
42
|
+
"valid": { "type": "integer", "minimum": 0 },
|
|
43
|
+
"invalid": { "type": "integer", "minimum": 0 },
|
|
44
|
+
"superseded": { "type": "integer", "minimum": 0, "description": "Records a closed record supersedes, counted before --current leaves them out." }
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"record": {
|
|
50
|
+
"type": "object",
|
|
51
|
+
"required": ["id", "path", "state", "valid", "reasons", "supersededBy", "data"],
|
|
52
|
+
"properties": {
|
|
53
|
+
"id": { "type": ["string", "null"], "description": "Null when the front matter could not be parsed or has no string id." },
|
|
54
|
+
"path": { "type": "string", "description": "From the repository root, with / separators." },
|
|
55
|
+
"state": { "type": ["string", "null"], "description": "The state as the record writes it. Supersession is reported in supersededBy, not here." },
|
|
56
|
+
"valid": { "type": "boolean", "description": "True exactly when reasons is empty." },
|
|
57
|
+
"reasons": { "type": "array", "items": { "$ref": "#/$defs/reason" } },
|
|
58
|
+
"supersededBy": {
|
|
59
|
+
"type": ["string", "null"],
|
|
60
|
+
"description": "The id of the closed record whose supersedes link replaces this one. Derived from that record's link, never from this record's own fields."
|
|
61
|
+
},
|
|
62
|
+
"data": {
|
|
63
|
+
"type": ["object", "null"],
|
|
64
|
+
"description": "The front matter as JSON, following the kind's schema when valid is true. Null when it could not be parsed."
|
|
65
|
+
},
|
|
66
|
+
"provenance": { "$ref": "#/$defs/provenance" }
|
|
67
|
+
},
|
|
68
|
+
"allOf": [
|
|
69
|
+
{
|
|
70
|
+
"if": { "properties": { "valid": { "const": true } } },
|
|
71
|
+
"then": { "properties": { "reasons": { "type": "array", "maxItems": 0 }, "data": { "type": "object" }, "id": { "type": "string" } } },
|
|
72
|
+
"else": { "properties": { "reasons": { "type": "array", "minItems": 1 } } }
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
},
|
|
76
|
+
"trust": {
|
|
77
|
+
"description": "Added in contract 1 by #2547. Where provenance was judged from: the policy read at the base revision, never the tree read.",
|
|
78
|
+
"type": "object",
|
|
79
|
+
"required": ["base", "baseFrom", "active", "signersPath", "problems"],
|
|
80
|
+
"properties": {
|
|
81
|
+
"base": { "type": ["string", "null"], "pattern": "^[0-9a-f]{40,64}$", "description": "The full commit id the policy was read at, or null when there is no base." },
|
|
82
|
+
"baseFrom": { "enum": ["flag", "origin/HEAD", "main", "master", null], "description": "flag when --base was given; otherwise the target branch that was found." },
|
|
83
|
+
"active": { "type": "boolean", "description": "Whether a signers file exists at base. False means attestation is off and every record is unattested." },
|
|
84
|
+
"signersPath": { "type": "string", "description": "The signers file, relative to the repository root." },
|
|
85
|
+
"problems": { "type": "array", "items": { "type": "string" }, "description": "Why the policy could not be read. Nothing is attested when this is not empty." }
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
"provenance": {
|
|
89
|
+
"description": "Added in contract 1 by #2547. How far the record's authorship is established, judged by the signers at base.",
|
|
90
|
+
"type": "object",
|
|
91
|
+
"required": ["level", "commit", "reason"],
|
|
92
|
+
"properties": {
|
|
93
|
+
"level": {
|
|
94
|
+
"enum": ["attested", "attested-unverifiable-here", "adopted", "unattested"],
|
|
95
|
+
"description": "attested: the last commit to change the file is signed by a signer the policy at base lists. attested-unverifiable-here: it carries a signature nothing here can check. adopted: it lies in a commit range the policy adopts. unattested: none of these, including uncommitted content."
|
|
96
|
+
},
|
|
97
|
+
"commit": { "type": ["string", "null"], "pattern": "^[0-9a-f]{40,64}$", "description": "The commit the record's content comes from, or null for uncommitted content." },
|
|
98
|
+
"attestor": { "type": "string", "description": "The attestor that answered, such as ssh-commit." },
|
|
99
|
+
"principal": { "type": "string", "description": "The signer, when attested." },
|
|
100
|
+
"key": { "type": "string", "description": "The signing key's fingerprint, when known." },
|
|
101
|
+
"reason": { "type": "string" }
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
"reason": {
|
|
105
|
+
"type": "object",
|
|
106
|
+
"required": ["code", "message"],
|
|
107
|
+
"properties": {
|
|
108
|
+
"code": {
|
|
109
|
+
"enum": [
|
|
110
|
+
"record-unparseable",
|
|
111
|
+
"record-schema-invalid",
|
|
112
|
+
"record-id-duplicate",
|
|
113
|
+
"record-supersedes-unknown",
|
|
114
|
+
"record-supersedes-conflict"
|
|
115
|
+
]
|
|
116
|
+
},
|
|
117
|
+
"message": { "type": "string" }
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
"failure": {
|
|
121
|
+
"description": "The read failed and returned no records. Exit code 1.",
|
|
122
|
+
"type": "object",
|
|
123
|
+
"required": ["$schema", "contract", "error"],
|
|
124
|
+
"properties": {
|
|
125
|
+
"$schema": { "const": "https://intentius.io/chant/schemas/workspace/records/v1/records.schema.json" },
|
|
126
|
+
"contract": { "const": 1 },
|
|
127
|
+
"error": {
|
|
128
|
+
"type": "object",
|
|
129
|
+
"required": ["code", "message"],
|
|
130
|
+
"properties": {
|
|
131
|
+
"code": {
|
|
132
|
+
"enum": [
|
|
133
|
+
"kind-unreadable",
|
|
134
|
+
"kind-invalid",
|
|
135
|
+
"schema-unreadable",
|
|
136
|
+
"schema-id-mismatch",
|
|
137
|
+
"schema-invalid",
|
|
138
|
+
"location-missing",
|
|
139
|
+
"not-a-git-repository",
|
|
140
|
+
"revision-unknown"
|
|
141
|
+
]
|
|
142
|
+
},
|
|
143
|
+
"message": { "type": "string" }
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
"records": false
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|