@intentius/chant 0.124.13 → 0.124.14
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/bin/chant +11 -0
- package/dist/agents/checks.js +326 -0
- package/dist/agents/discover.js +885 -0
- package/dist/agents/importer.js +17 -0
- package/dist/agents/index.js +12 -0
- package/dist/agents/types.js +19 -0
- package/dist/apply.js +151 -0
- package/dist/attrref.js +70 -0
- package/dist/audit/catalog.js +350 -0
- package/dist/audit/core.js +252 -0
- package/dist/audit/discover.js +633 -0
- package/dist/audit/fetch.js +666 -0
- package/dist/audit/lineage.js +91 -0
- package/dist/audit/nginx.js +366 -0
- package/dist/audit/prior-art.js +132 -0
- package/dist/audit/proof.js +321 -0
- package/dist/audit/report-html.js +194 -0
- package/dist/audit/report-model.js +198 -0
- package/dist/audit/report.js +102 -0
- package/dist/audit/rules-doc.js +144 -0
- package/dist/audit/secrets.js +405 -0
- package/dist/audit/terraform-state.js +140 -0
- package/dist/audit/wrangler.js +262 -0
- package/dist/behaviour-delta.js +401 -0
- package/dist/behaviour-engine.js +357 -0
- package/dist/behaviour-graph.js +83 -0
- package/dist/behaviour-http.js +188 -0
- package/dist/behaviour-kinds.js +172 -0
- package/dist/behaviour-overlay.js +50 -0
- package/dist/behaviour-predict.js +188 -0
- package/dist/behaviour-request.js +194 -0
- package/dist/behaviour.js +1325 -0
- package/dist/build-params.js +108 -0
- package/dist/build.js +668 -0
- package/dist/builder.js +44 -0
- package/dist/cdk/advise.js +30 -0
- package/dist/cdk/assembly.js +122 -0
- package/dist/cdk/graph.js +444 -0
- package/dist/cdk/tier-map.js +64 -0
- package/dist/cdk/types.js +24 -0
- package/dist/change-set.js +312 -0
- package/dist/child-project.js +21 -0
- package/dist/claimed-fields.js +135 -0
- package/dist/cli/build-options.js +70 -0
- package/dist/cli/build-params-cli.js +139 -0
- package/dist/cli/command-group.js +123 -0
- package/dist/cli/commands/audit-agents.js +326 -0
- package/dist/cli/commands/audit.js +571 -0
- package/dist/cli/commands/build.js +920 -0
- package/dist/cli/commands/carve-apply.js +153 -0
- package/dist/cli/commands/carve-bridge.js +201 -0
- package/dist/cli/commands/carve-emit.js +332 -0
- package/dist/cli/commands/carve-status.js +119 -0
- package/dist/cli/commands/carve.js +204 -0
- package/dist/cli/commands/check-lexicon-docs.js +79 -0
- package/dist/cli/commands/check-lexicon-examples.js +177 -0
- package/dist/cli/commands/check-lexicon-intrinsics.js +291 -0
- package/dist/cli/commands/check-lexicon-mcp.js +82 -0
- package/dist/cli/commands/check-lexicon-plugin.d.ts.map +1 -1
- package/dist/cli/commands/check-lexicon-plugin.js +104 -0
- package/dist/cli/commands/check-lexicon.js +766 -0
- package/dist/cli/commands/describe.js +85 -0
- package/dist/cli/commands/diff.js +175 -0
- package/dist/cli/commands/doctor.js +350 -0
- package/dist/cli/commands/import-agents.js +155 -0
- package/dist/cli/commands/import.js +670 -0
- package/dist/cli/commands/init-lexicon/templates/codegen.js +194 -0
- package/dist/cli/commands/init-lexicon/templates/docs.js +100 -0
- package/dist/cli/commands/init-lexicon/templates/examples.js +29 -0
- package/dist/cli/commands/init-lexicon/templates/lint.js +34 -0
- package/dist/cli/commands/init-lexicon/templates/lsp.js +37 -0
- package/dist/cli/commands/init-lexicon/templates/plugin.js +108 -0
- package/dist/cli/commands/init-lexicon/templates/project.js +240 -0
- package/dist/cli/commands/init-lexicon/templates/spec.js +56 -0
- package/dist/cli/commands/init-lexicon/templates/tests.js +66 -0
- package/dist/cli/commands/init-lexicon.js +172 -0
- package/dist/cli/commands/init.js +381 -0
- package/dist/cli/commands/lexicon-rolling-upgrade.js +145 -0
- package/dist/cli/commands/lexicon-surface-diff.js +145 -0
- package/dist/cli/commands/licenses.js +125 -0
- package/dist/cli/commands/lint.d.ts.map +1 -1
- package/dist/cli/commands/lint.js +948 -0
- package/dist/cli/commands/list.js +63 -0
- package/dist/cli/commands/migrate.d.ts.map +1 -1
- package/dist/cli/commands/migrate.js +423 -0
- package/dist/cli/commands/onboard.js +403 -0
- package/dist/cli/commands/pinned-upgrade.js +191 -0
- package/dist/cli/commands/update.js +194 -0
- package/dist/cli/commands/vendor.js +217 -0
- package/dist/cli/conflict-check.js +104 -0
- package/dist/cli/debug.js +8 -0
- package/dist/cli/format.js +104 -0
- package/dist/cli/handlers/build.js +267 -0
- package/dist/cli/handlers/carve-apply.js +30 -0
- package/dist/cli/handlers/carve-bridge.js +28 -0
- package/dist/cli/handlers/carve-emit.js +50 -0
- package/dist/cli/handlers/carve-status.js +26 -0
- package/dist/cli/handlers/carve.js +40 -0
- package/dist/cli/handlers/change-set.js +46 -0
- package/dist/cli/handlers/components.js +730 -0
- package/dist/cli/handlers/dev.js +113 -0
- package/dist/cli/handlers/emulator.js +233 -0
- package/dist/cli/handlers/explain.js +54 -0
- package/dist/cli/handlers/fan-out.js +422 -0
- package/dist/cli/handlers/gate-resume.js +275 -0
- package/dist/cli/handlers/generate.js +84 -0
- package/dist/cli/handlers/graph.js +969 -0
- package/dist/cli/handlers/init.js +102 -0
- package/dist/cli/handlers/lifecycle.js +1727 -0
- package/dist/cli/handlers/lint.js +62 -0
- package/dist/cli/handlers/migrate.js +48 -0
- package/dist/cli/handlers/misc.js +391 -0
- package/dist/cli/handlers/operator.js +1162 -0
- package/dist/cli/handlers/override-approve.js +102 -0
- package/dist/cli/handlers/pr.js +503 -0
- package/dist/cli/handlers/promote.js +342 -0
- package/dist/cli/handlers/run-generate.js +206 -0
- package/dist/cli/handlers/run-wave.js +66 -0
- package/dist/cli/handlers/run.js +1191 -0
- package/dist/cli/handlers/scenario.js +325 -0
- package/dist/cli/handlers/search.js +924 -0
- package/dist/cli/handlers/serve.js +32 -0
- package/dist/cli/handlers/vendor.js +154 -0
- package/dist/cli/index.js +3 -0
- package/dist/cli/is-entry-point.js +23 -0
- package/dist/cli/lsp/capabilities.js +28 -0
- package/dist/cli/lsp/diagnostics.js +34 -0
- package/dist/cli/lsp/server.js +329 -0
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +2540 -0
- package/dist/cli/mcp/lifecycle-tools.js +80 -0
- package/dist/cli/mcp/op-tools.js +306 -0
- package/dist/cli/mcp/resource-handlers.js +258 -0
- package/dist/cli/mcp/resources/context.js +85 -0
- package/dist/cli/mcp/server.js +353 -0
- package/dist/cli/mcp/tools/build.js +111 -0
- package/dist/cli/mcp/tools/composites.js +95 -0
- package/dist/cli/mcp/tools/explain.js +166 -0
- package/dist/cli/mcp/tools/import.js +49 -0
- package/dist/cli/mcp/tools/lint.js +41 -0
- package/dist/cli/mcp/tools/scaffold.js +111 -0
- package/dist/cli/mcp/tools/search.js +112 -0
- package/dist/cli/mcp/types.js +1 -0
- package/dist/cli/mcp/workspace-plugins.js +91 -0
- package/dist/cli/mcp/workspace-tools.d.ts +1 -1
- package/dist/cli/mcp/workspace-tools.js +564 -0
- package/dist/cli/mcp-config.js +70 -0
- package/dist/cli/plugins.js +313 -0
- package/dist/cli/registry.js +23 -0
- package/dist/cli/reporters/stylish.js +329 -0
- package/dist/cli/version.js +15 -0
- package/dist/cli/watch.js +79 -0
- package/dist/codegen/bound-property-types.js +82 -0
- package/dist/codegen/coverage.js +119 -0
- package/dist/codegen/docs-file-markers.js +60 -0
- package/dist/codegen/docs-pages.js +115 -0
- package/dist/codegen/docs-rule-scanning.js +164 -0
- package/dist/codegen/docs-rules.js +76 -0
- package/dist/codegen/docs-sections.js +117 -0
- package/dist/codegen/docs-sidebar.js +65 -0
- package/dist/codegen/docs-types.js +4 -0
- package/dist/codegen/docs.js +356 -0
- package/dist/codegen/fetch.js +340 -0
- package/dist/codegen/generate-post-synth-barrel.js +63 -0
- package/dist/codegen/generate-registry.js +71 -0
- package/dist/codegen/generate-runtime-index.js +56 -0
- package/dist/codegen/generate-typescript.js +119 -0
- package/dist/codegen/generate.js +115 -0
- package/dist/codegen/json-patch.js +141 -0
- package/dist/codegen/json-schema-to-ts.js +344 -0
- package/dist/codegen/json-schema.js +246 -0
- package/dist/codegen/lexicon-regen.js +412 -0
- package/dist/codegen/naming.js +217 -0
- package/dist/codegen/okf-lexicon.js +245 -0
- package/dist/codegen/package.js +150 -0
- package/dist/codegen/pinned-upgrade.d.ts.map +1 -1
- package/dist/codegen/pinned-upgrade.js +494 -0
- package/dist/codegen/registry.js +60 -0
- package/dist/codegen/rehype-base-url.mjs +68 -0
- package/dist/codegen/rolling-upgrade.js +217 -0
- package/dist/codegen/surface-snapshot.js +537 -0
- package/dist/codegen/testdata/postgres-tags.json +242 -0
- package/dist/codegen/topo-sort.js +36 -0
- package/dist/codegen/typecheck.js +115 -0
- package/dist/codegen/validate.js +200 -0
- package/dist/codegen/version-bump.js +35 -0
- package/dist/components/auto-release.js +143 -0
- package/dist/components/builders.js +47 -0
- package/dist/components/capability-plugin-loader.js +175 -0
- package/dist/components/capability-plugin-schema.js +46 -0
- package/dist/components/capability-plugin.js +99 -0
- package/dist/components/capability.js +60 -0
- package/dist/components/changed-files.js +72 -0
- package/dist/components/cli-support.js +427 -0
- package/dist/components/component.js +120 -0
- package/dist/components/component.schema.json +271 -0
- package/dist/components/config-defaults.js +130 -0
- package/dist/components/deploy-units.js +60 -0
- package/dist/components/discover.d.ts.map +1 -1
- package/dist/components/discover.js +189 -0
- package/dist/components/driver-output.js +86 -0
- package/dist/components/driver.js +728 -0
- package/dist/components/fan-out-output.js +165 -0
- package/dist/components/fan-out-record.js +94 -0
- package/dist/components/fan-out-run.js +373 -0
- package/dist/components/fan-out-support.js +60 -0
- package/dist/components/fan-out.js +273 -0
- package/dist/components/gate-plan.js +41 -0
- package/dist/components/gated-wave-pipeline.js +46 -0
- package/dist/components/index.js +24 -0
- package/dist/components/layers.js +28 -0
- package/dist/components/manifest-persistence.js +108 -0
- package/dist/components/pilots/alb-ecs.pilot.js +59 -0
- package/dist/components/pilots/dynamodb.pilot.js +51 -0
- package/dist/components/pilots/jar-emr.pilot.js +65 -0
- package/dist/components/pilots/lambda.pilot.js +52 -0
- package/dist/components/pilots/neo4j-fanout.pilot.js +68 -0
- package/dist/components/pilots/project.js +12 -0
- package/dist/components/pr-pipeline.js +134 -0
- package/dist/components/pr-run.js +363 -0
- package/dist/components/presets/ecs-fargate.js +72 -0
- package/dist/components/presets/index.js +28 -0
- package/dist/components/presets/lambda.js +34 -0
- package/dist/components/presets/single-host-compose.js +41 -0
- package/dist/components/promote.js +549 -0
- package/dist/components/registry.js +34 -0
- package/dist/components/run-progress.js +33 -0
- package/dist/components/sandbox/driver.d.ts.map +1 -1
- package/dist/components/sandbox/driver.js +93 -0
- package/dist/components/sandbox/run.js +115 -0
- package/dist/components/starter-plugin.js +104 -0
- package/dist/components/verbs/__tests__/mock-cloud-executor.js +68 -0
- package/dist/components/verbs/__tests__/mock-process-runner.js +45 -0
- package/dist/components/verbs/__tests__/mock-sbom-generator.js +56 -0
- package/dist/components/verbs/bom-writer.js +287 -0
- package/dist/components/verbs/build-archive.js +188 -0
- package/dist/components/verbs/build.js +142 -0
- package/dist/components/verbs/cloud-executor.js +110 -0
- package/dist/components/verbs/component-bom.js +125 -0
- package/dist/components/verbs/ensure-secret.js +50 -0
- package/dist/components/verbs/index.js +61 -0
- package/dist/components/verbs/license-policy.js +75 -0
- package/dist/components/verbs/lockfile-sbom-generator.js +191 -0
- package/dist/components/verbs/process-runner.js +78 -0
- package/dist/components/verbs/r2-sync.js +93 -0
- package/dist/components/verbs/reproducibility.js +62 -0
- package/dist/components/verbs/run-agent.js +577 -0
- package/dist/components/verbs/sbom-generator.js +119 -0
- package/dist/components/verbs/sbom.js +97 -0
- package/dist/components/verbs/shell.js +32 -0
- package/dist/components/verbs/sign.js +221 -0
- package/dist/components/verbs/stub.js +28 -0
- package/dist/components/verbs/tool-sbom-generator.js +154 -0
- package/dist/components/verbs/verify.js +112 -0
- package/dist/components/verbs/vex.js +131 -0
- package/dist/components/verbs/vuln-gate.js +152 -0
- package/dist/components/verbs/vuln-scan.js +288 -0
- package/dist/components/verbs/wait-verify.js +106 -0
- package/dist/components/verbs/wrangler.js +179 -0
- package/dist/components/wave-plan.js +102 -0
- package/dist/composite.js +305 -0
- package/dist/config-import.d.ts.map +1 -1
- package/dist/config-import.js +22 -0
- package/dist/config-sandbox.js +122 -0
- package/dist/config-static.js +206 -0
- package/dist/config.js +605 -0
- package/dist/content-digest.js +23 -0
- package/dist/declarable.js +114 -0
- package/dist/deep-observation.js +437 -0
- package/dist/detectLexicon.js +54 -0
- package/dist/discovery/cache.js +70 -0
- package/dist/discovery/collect.js +208 -0
- package/dist/discovery/cycles.js +95 -0
- package/dist/discovery/entity-wire-codec.js +391 -0
- package/dist/discovery/entity-wire.js +42 -0
- package/dist/discovery/files.js +121 -0
- package/dist/discovery/fold-import.d.ts.map +1 -1
- package/dist/discovery/fold-import.js +4178 -0
- package/dist/discovery/fold-rank.js +292 -0
- package/dist/discovery/graph.js +115 -0
- package/dist/discovery/import.d.ts.map +1 -1
- package/dist/discovery/import.js +65 -0
- package/dist/discovery/index.js +333 -0
- package/dist/discovery/param-deps.js +487 -0
- package/dist/discovery/resolve.js +39 -0
- package/dist/discovery/sandbox/bundle.js +214 -0
- package/dist/discovery/sandbox/child-errors.js +26 -0
- package/dist/discovery/sandbox/config-run.js +100 -0
- package/dist/discovery/sandbox/config-wire.js +183 -0
- package/dist/discovery/sandbox/driver.d.ts.map +1 -1
- package/dist/discovery/sandbox/driver.js +333 -0
- package/dist/discovery/sandbox/fork.js +229 -0
- package/dist/discovery/sandbox/policy-run.js +142 -0
- package/dist/discovery/sandbox/policy-wire.js +152 -0
- package/dist/discovery/sandbox/run.js +77 -0
- package/dist/discovery/specifier-resolve.js +320 -0
- package/dist/discovery/walk.js +284 -0
- package/dist/effect-receipt.js +340 -0
- package/dist/env.js +55 -0
- package/dist/errors.js +62 -0
- package/dist/fold/fold.js +1434 -0
- package/dist/fold/foldable-helpers.js +229 -0
- package/dist/fold/subset.js +696 -0
- package/dist/fold-provenance.js +414 -0
- package/dist/gate-decision.js +260 -0
- package/dist/gate-resume-run.js +154 -0
- package/dist/gated-waves.js +165 -0
- package/dist/governance.js +43 -0
- package/dist/graph-declared.js +45 -0
- package/dist/graph-detail.js +207 -0
- package/dist/graph-dot.js +54 -0
- package/dist/graph-effective.js +107 -0
- package/dist/graph-ir.js +623 -0
- package/dist/graph-layout.js +184 -0
- package/dist/graph-lens.js +105 -0
- package/dist/graph-mermaid.js +83 -0
- package/dist/graph-ops.js +39 -0
- package/dist/graph-refs.js +156 -0
- package/dist/held-elsewhere.js +87 -0
- package/dist/identity.js +251 -0
- package/dist/import/base-parser.js +34 -0
- package/dist/import/embedded.js +255 -0
- package/dist/import/generator.js +1 -0
- package/dist/import/ir-utils.js +85 -0
- package/dist/import/parser-options.js +45 -0
- package/dist/import/parser.js +1 -0
- package/dist/index.js +118 -0
- package/dist/intrinsic-interpolation.js +73 -0
- package/dist/intrinsic.js +31 -0
- package/dist/join-key.js +35 -0
- package/dist/kubectl-context.js +150 -0
- package/dist/lexicon-config.js +58 -0
- package/dist/lexicon-integrity.js +47 -0
- package/dist/lexicon-manifest.js +70 -0
- package/dist/lexicon-module.d.ts.map +1 -1
- package/dist/lexicon-module.js +241 -0
- package/dist/lexicon-output.js +218 -0
- package/dist/lexicon-plugin-helpers.js +104 -0
- package/dist/lexicon-schema.js +136 -0
- package/dist/lexicon.js +130 -0
- package/dist/lifecycle/affected.js +224 -0
- package/dist/lifecycle/assert-live.js +110 -0
- package/dist/lifecycle/build-ledger-store.js +160 -0
- package/dist/lifecycle/build-ledger.js +155 -0
- package/dist/lifecycle/change-set.js +356 -0
- package/dist/lifecycle/converge-ledger.js +161 -0
- package/dist/lifecycle/deep-diff.js +233 -0
- package/dist/lifecycle/deep-observe.js +147 -0
- package/dist/lifecycle/digest.js +143 -0
- package/dist/lifecycle/disruption.js +135 -0
- package/dist/lifecycle/gate-applied.js +113 -0
- package/dist/lifecycle/gate-audit.js +341 -0
- package/dist/lifecycle/gate-ledger-select.js +89 -0
- package/dist/lifecycle/gate-ledger.js +193 -0
- package/dist/lifecycle/gate-origin.js +117 -0
- package/dist/lifecycle/gate-pending.js +58 -0
- package/dist/lifecycle/git.js +1182 -0
- package/dist/lifecycle/identity.js +58 -0
- package/dist/lifecycle/index.js +26 -0
- package/dist/lifecycle/lease.js +283 -0
- package/dist/lifecycle/ledger-port.js +1 -0
- package/dist/lifecycle/legacy-digest.js +91 -0
- package/dist/lifecycle/live-diff.js +274 -0
- package/dist/lifecycle/local-note.js +15 -0
- package/dist/lifecycle/member-ledger.js +122 -0
- package/dist/lifecycle/observation-baseline.js +155 -0
- package/dist/lifecycle/observe.js +375 -0
- package/dist/lifecycle/oras-referrer-lookup.js +82 -0
- package/dist/lifecycle/override-ledger.js +54 -0
- package/dist/lifecycle/plan-digest.js +110 -0
- package/dist/lifecycle/plan-ledger.js +129 -0
- package/dist/lifecycle/receipt-plan.js +192 -0
- package/dist/lifecycle/release-ledger.js +155 -0
- package/dist/lifecycle/release-read.js +64 -0
- package/dist/lifecycle/replay.js +193 -0
- package/dist/lifecycle/rollback.js +102 -0
- package/dist/lifecycle/run-ledger.js +183 -0
- package/dist/lifecycle/scenario-eval.js +204 -0
- package/dist/lifecycle/scenario.js +214 -0
- package/dist/lifecycle/snapshot.js +239 -0
- package/dist/lifecycle/status.js +447 -0
- package/dist/lifecycle/symptoms.js +117 -0
- package/dist/lifecycle/teardown.js +255 -0
- package/dist/lifecycle/types.js +1 -0
- package/dist/lifecycle/unobserved-gate.js +33 -0
- package/dist/lifecycle/wave-plans.js +68 -0
- package/dist/lifecycle/work-item-id.js +36 -0
- package/dist/lifecycle/work-lease.js +393 -0
- package/dist/lint/component-checks.js +87 -0
- package/dist/lint/config.js +483 -0
- package/dist/lint/declarative.js +122 -0
- package/dist/lint/discover.d.ts.map +1 -1
- package/dist/lint/discover.js +138 -0
- package/dist/lint/engine.js +246 -0
- package/dist/lint/knowledge-checks.js +64 -0
- package/dist/lint/named-checks.js +22 -0
- package/dist/lint/output-checks.js +87 -0
- package/dist/lint/output-docs.js +163 -0
- package/dist/lint/parser.js +33 -0
- package/dist/lint/pipeline-change-gate.js +70 -0
- package/dist/lint/policy-import.d.ts +1 -1
- package/dist/lint/policy-import.d.ts.map +1 -1
- package/dist/lint/policy-import.js +62 -0
- package/dist/lint/policy-sandbox.js +86 -0
- package/dist/lint/policy.js +122 -0
- package/dist/lint/post-synth.js +87 -0
- package/dist/lint/presets/relaxed.json +26 -0
- package/dist/lint/presets/strict.json +24 -24
- package/dist/lint/receipt-checks.js +83 -0
- package/dist/lint/rule-loader.d.ts.map +1 -1
- package/dist/lint/rule-loader.js +89 -0
- package/dist/lint/rule-registry.js +86 -0
- package/dist/lint/rule.js +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-a.component.js +7 -0
- package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-b.component.js +7 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/fail/orphan-lib.component.js +9 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/pass/emr-job.component.js +11 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/pass/jar-lib.component.js +9 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/fail/search-service.component.js +25 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/pass/jar-lib.component.js +8 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/pass/search-service.component.js +21 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/fail/migrator.component.js +8 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/pass/agent-turn.component.js +24 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/pass/migrator.component.js +17 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/pass/orders-table.component.js +8 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/fail/neo4j-cluster.component.js +18 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.js +20 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.js +8 -0
- package/dist/lint/rules/__fixtures__/comp/comp005/fail/search-service.component.js +12 -0
- package/dist/lint/rules/__fixtures__/comp/comp005/pass/search-service.component.js +16 -0
- package/dist/lint/rules/__fixtures__/comp/comp006/fail/legacy-tool.component.js +8 -0
- package/dist/lint/rules/__fixtures__/comp/comp006/pass/legacy-tool.component.js +12 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/fail/inventory-table.component.js +11 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/fail/orders-table.component.js +11 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/pass/orders-table.component.js +10 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/pass/search-service.component.js +16 -0
- package/dist/lint/rules/comp/comp001-publishes-never-applies.js +69 -0
- package/dist/lint/rules/comp/comp002-dangling-wiring-ref.js +84 -0
- package/dist/lint/rules/comp/comp003-mutating-no-rollback.js +103 -0
- package/dist/lint/rules/comp/comp004-gate-needs-durable-runtime.js +70 -0
- package/dist/lint/rules/comp/comp005-capability-kind-is-noun.js +109 -0
- package/dist/lint/rules/comp/comp006-shell-needs-reason.js +49 -0
- package/dist/lint/rules/comp/comp007-composition-sprawl.js +64 -0
- package/dist/lint/rules/comp/index.js +33 -0
- package/dist/lint/rules/comp/support.js +129 -0
- package/dist/lint/rules/composite-scope.js +51 -0
- package/dist/lint/rules/cor017-composite-name-match.js +93 -0
- package/dist/lint/rules/cor018-composite-prefer-lexicon-type.js +136 -0
- package/dist/lint/rules/cor021-env-literal-name.js +100 -0
- package/dist/lint/rules/cor022-receipt-leaf.js +118 -0
- package/dist/lint/rules/cor024-receipt-secret-pointer.js +199 -0
- package/dist/lint/rules/declarable-naming-convention.js +62 -0
- package/dist/lint/rules/evl001-non-literal-expression.js +66 -0
- package/dist/lint/rules/evl002-control-flow-resource.js +69 -0
- package/dist/lint/rules/evl003-dynamic-property-access.js +44 -0
- package/dist/lint/rules/evl004-spread-non-const.js +94 -0
- package/dist/lint/rules/evl005-resource-block-body.js +41 -0
- package/dist/lint/rules/evl007-invalid-siblings.js +105 -0
- package/dist/lint/rules/evl009-composite-no-constant.js +158 -0
- package/dist/lint/rules/evl010-composite-no-transform.js +59 -0
- package/dist/lint/rules/evl011-symbolic-in-template.js +106 -0
- package/dist/lint/rules/export-required.js +115 -0
- package/dist/lint/rules/file-declarable-limit.js +88 -0
- package/dist/lint/rules/flat-declarations.js +62 -0
- package/dist/lint/rules/index.js +90 -0
- package/dist/lint/rules/no-cyclic-declarable-ref.js +138 -0
- package/dist/lint/rules/no-redundant-type-import.js +76 -0
- package/dist/lint/rules/no-redundant-value-cast.js +41 -0
- package/dist/lint/rules/no-string-ref.js +59 -0
- package/dist/lint/rules/no-unused-declarable-import.js +75 -0
- package/dist/lint/rules/no-unused-declarable.js +142 -0
- package/dist/lint/rules/op/index.js +28 -0
- package/dist/lint/rules/op/ops012-activity-contract.js +54 -0
- package/dist/lint/rules/op/ops013-step-output-ref.js +88 -0
- package/dist/lint/rules/op/ops014-converge-rule-refusals.js +114 -0
- package/dist/lint/rules/op/ops015-gate-approval.js +45 -0
- package/dist/lint/rules/op/support.js +11 -0
- package/dist/lint/rules/op/sys010-key-over-plain-http.js +100 -0
- package/dist/lint/rules/property-kind.js +56 -0
- package/dist/lint/rules/single-concern-file.js +71 -0
- package/dist/lint/rules/sys001-no-literal-key.js +60 -0
- package/dist/lint/selectors.js +168 -0
- package/dist/lint/suppressions.js +129 -0
- package/dist/lint/typescript.js +17 -0
- package/dist/live-endpoint.js +113 -0
- package/dist/live-read-session.js +76 -0
- package/dist/lsp/lexicon-providers.js +163 -0
- package/dist/lsp/types.js +5 -0
- package/dist/managed-fields.js +293 -0
- package/dist/mcp/types.js +4 -0
- package/dist/notify-verify.js +0 -1
- package/dist/notify.js +0 -1
- package/dist/notify.schema.json +72 -0
- package/dist/observation.js +266 -0
- package/dist/okf-read.js +134 -0
- package/dist/okf.js +275 -0
- package/dist/op/__fixtures__/decide-stub-backend.js +125 -0
- package/dist/op/activities/activity-contracts.js +313 -0
- package/dist/op/activities/apply.js +582 -0
- package/dist/op/activities/build.js +18 -0
- package/dist/op/activities/change-coverage.js +40 -0
- package/dist/op/activities/change-set.js +64 -0
- package/dist/op/activities/converge.js +492 -0
- package/dist/op/activities/decide.js +211 -0
- package/dist/op/activities/env-teardown.js +110 -0
- package/dist/op/activities/factory.js +591 -0
- package/dist/op/activities/forge-pull-request.js +82 -0
- package/dist/op/activities/gh-host.js +78 -0
- package/dist/op/activities/guard-validate.js +165 -0
- package/dist/op/activities/http-check.js +40 -0
- package/dist/op/activities/index.js +59 -0
- package/dist/op/activities/lexicon-upgrade.js +629 -0
- package/dist/op/activities/lifecycle.js +109 -0
- package/dist/op/activities/pipeline-audit.js +147 -0
- package/dist/op/activities/policy.js +26 -0
- package/dist/op/activities/predict-behaviour.js +341 -0
- package/dist/op/activities/propose-upgrade.js +165 -0
- package/dist/op/activities/reconcile.js +997 -0
- package/dist/op/activities/shell.js +118 -0
- package/dist/op/activities/source-release.js +97 -0
- package/dist/op/activities/source-rollback.js +165 -0
- package/dist/op/activities/teardown.js +17 -0
- package/dist/op/activities/util.js +6 -0
- package/dist/op/activities/wait.js +51 -0
- package/dist/op/activities/work-evidence.js +35 -0
- package/dist/op/activities/workflow-audit.js +133 -0
- package/dist/op/activity-contract-registry.js +106 -0
- package/dist/op/activity-contract.js +232 -0
- package/dist/op/activity-failure.js +31 -0
- package/dist/op/activity-profiles.js +129 -0
- package/dist/op/activity-registry.js +105 -0
- package/dist/op/activity-runtime.js +28 -0
- package/dist/op/builders.js +801 -0
- package/dist/op/change-signal.js +118 -0
- package/dist/op/composites/apply-op.js +151 -0
- package/dist/op/composites/behaviour-op.js +65 -0
- package/dist/op/composites/converge-op.js +141 -0
- package/dist/op/composites/index.js +19 -0
- package/dist/op/composites/lexicon-upgrade-op.js +107 -0
- package/dist/op/composites/pipeline-audit-op.js +50 -0
- package/dist/op/composites/reconcile-op.js +84 -0
- package/dist/op/composites/watch-op.js +69 -0
- package/dist/op/composites/workflow-audit-op.js +57 -0
- package/dist/op/converge-rule.js +205 -0
- package/dist/op/cron.js +146 -0
- package/dist/op/decide-backend.js +181 -0
- package/dist/op/decide-config.js +68 -0
- package/dist/op/decide-read-inputs.js +141 -0
- package/dist/op/discover.d.ts.map +1 -1
- package/dist/op/discover.js +213 -0
- package/dist/op/duration.js +21 -0
- package/dist/op/emulator-freshness.js +80 -0
- package/dist/op/emulator-lifecycle.js +269 -0
- package/dist/op/factory.js +83 -0
- package/dist/op/gate-approval.js +172 -0
- package/dist/op/gate-name.js +86 -0
- package/dist/op/gate-plan-context.js +167 -0
- package/dist/op/gate-point-run.js +67 -0
- package/dist/op/gate-point.js +111 -0
- package/dist/op/gate-resume-plan.js +155 -0
- package/dist/op/gate-resume.js +31 -0
- package/dist/op/gate-review.js +290 -0
- package/dist/op/gate-run-locator.js +85 -0
- package/dist/op/gate-summary.js +100 -0
- package/dist/op/gate-wait.js +56 -0
- package/dist/op/gate.js +449 -0
- package/dist/op/generate-pipeline.js +124 -0
- package/dist/op/index.js +51 -0
- package/dist/op/lifecycle-receipt-store.js +45 -0
- package/dist/op/local-executor.js +1164 -0
- package/dist/op/local-output.js +140 -0
- package/dist/op/op-ir.js +317 -0
- package/dist/op/op-verb-class.js +131 -0
- package/dist/op/op-waves-notify.js +136 -0
- package/dist/op/op-waves-run.js +1657 -0
- package/dist/op/op-waves.js +409 -0
- package/dist/op/operator.js +743 -0
- package/dist/op/receipt-store.js +94 -0
- package/dist/op/resource.js +23 -0
- package/dist/op/run-context.js +28 -0
- package/dist/op/run-live.js +256 -0
- package/dist/op/runtime.js +21 -0
- package/dist/op/runtimes/local.js +195 -0
- package/dist/op/source-archive.js +131 -0
- package/dist/op/step-output-ref.js +397 -0
- package/dist/op/steward-beside.js +169 -0
- package/dist/op/steward-points.js +138 -0
- package/dist/op/steward-turn.js +59 -0
- package/dist/op/steward.js +317 -0
- package/dist/op/types.js +25 -0
- package/dist/op/work-lease-decl.js +81 -0
- package/dist/op/work-lease-run.js +393 -0
- package/dist/override-gate.js +284 -0
- package/dist/owner-chain.js +74 -0
- package/dist/ownership.js +92 -0
- package/dist/params.js +61 -0
- package/dist/plan-summary.js +711 -0
- package/dist/point-decision.js +211 -0
- package/dist/pr-forge.js +810 -0
- package/dist/pr-loop.js +203 -0
- package/dist/project-codegen.js +191 -0
- package/dist/project-root.js +74 -0
- package/dist/project-validation.js +50 -0
- package/dist/provenance.js +157 -0
- package/dist/pseudo-parameter.js +40 -0
- package/dist/reconcile.js +450 -0
- package/dist/resource-attributes.js +33 -0
- package/dist/runtime-adapter.js +77 -0
- package/dist/runtime.js +66 -0
- package/dist/secret-materialization.js +153 -0
- package/dist/secret-provenance.js +250 -0
- package/dist/serializer-walker.js +112 -0
- package/dist/serializer.js +1 -0
- package/dist/sort.js +45 -0
- package/dist/stack-output.js +115 -0
- package/dist/telemetry-attribution.js +149 -0
- package/dist/terraform/__fixtures__/build-graph.js +63 -0
- package/dist/terraform/adopt-state.js +40 -0
- package/dist/terraform/aws-resources.js +384 -0
- package/dist/terraform/bridge.js +204 -0
- package/dist/terraform/carve-provider.js +155 -0
- package/dist/terraform/carve.js +138 -0
- package/dist/terraform/data-source-shape.js +57 -0
- package/dist/terraform/emit-source.js +36 -0
- package/dist/terraform/excise.js +123 -0
- package/dist/terraform/graduate.js +128 -0
- package/dist/terraform/graph.js +435 -0
- package/dist/terraform/hcl2json.js +60 -0
- package/dist/terraform/manifest.js +149 -0
- package/dist/terraform/parse.js +81 -0
- package/dist/terraform/providers/aws.js +146 -0
- package/dist/terraform/providers/gcp.js +294 -0
- package/dist/terraform/providers/index.js +17 -0
- package/dist/terraform/providers/kubernetes.js +253 -0
- package/dist/terraform/score.js +151 -0
- package/dist/terraform/state.js +67 -0
- package/dist/terraform/tier-map.js +74 -0
- package/dist/terraform/types.js +13 -0
- package/dist/terraform/unified-diff.js +132 -0
- package/dist/testing.js +295 -0
- package/dist/toml-emit.js +153 -0
- package/dist/toml-parse.js +355 -0
- package/dist/toml-utils.js +60 -0
- package/dist/toml.js +428 -0
- package/dist/ts-loader.d.ts +46 -0
- package/dist/ts-loader.d.ts.map +1 -0
- package/dist/ts-loader.js +103 -0
- package/dist/types.js +1 -0
- package/dist/utils.js +61 -0
- package/dist/validation.js +20 -0
- package/dist/vendor/js-yaml-load.js +1662 -0
- package/dist/workspace/__fixtures__/contract-repo.js +103 -0
- package/dist/workspace/__fixtures__/decide-workspace.js +112 -0
- package/dist/workspace/__fixtures__/sessions.js +91 -0
- package/dist/workspace/__fixtures__/two-member-workspace.js +34 -0
- package/dist/workspace/agent-cli.js +99 -0
- package/dist/workspace/agent.schema.json +390 -0
- package/dist/workspace/answers-ledger.js +89 -0
- package/dist/workspace/box-cli.js +142 -0
- package/dist/workspace/box-factory-write.js +196 -0
- package/dist/workspace/box-factory-write.schema.json +342 -0
- package/dist/workspace/box-factory.js +88 -0
- package/dist/workspace/box-intent.js +126 -0
- package/dist/workspace/box-isolation.js +169 -0
- package/dist/workspace/box-listing-write.schema.json +204 -0
- package/dist/workspace/box-listing.js +298 -0
- package/dist/workspace/box-publish.js +352 -0
- package/dist/workspace/box-publish.schema.json +498 -0
- package/dist/workspace/box-services.js +39 -0
- package/dist/workspace/broker-protocol.js +359 -0
- package/dist/workspace/broker-protocol.schema.json +228 -0
- package/dist/workspace/change-set.schema.json +460 -0
- package/dist/workspace/changes-cli.js +56 -0
- package/dist/workspace/changes.js +446 -0
- package/dist/workspace/changes.schema.json +642 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-fly-site.js +198 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-live-names.js +155 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-rollback.js +214 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-ship-inputs.js +180 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-ship-policy.js +99 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit.js +847 -0
- package/dist/workspace/chant-migrations.js +113 -0
- package/dist/workspace/check.schema.json +433 -0
- package/dist/workspace/checks/box-isolation.js +62 -0
- package/dist/workspace/checks/boxes.js +491 -0
- package/dist/workspace/checks/diagrams.js +104 -0
- package/dist/workspace/checks/generated.js +419 -0
- package/dist/workspace/checks/ledgers.js +212 -0
- package/dist/workspace/checks/links.js +191 -0
- package/dist/workspace/checks/live.js +100 -0
- package/dist/workspace/checks/pipelines.js +188 -0
- package/dist/workspace/checks/records.js +169 -0
- package/dist/workspace/checks.js +426 -0
- package/dist/workspace/ci-green-cli.js +125 -0
- package/dist/workspace/ci-green-forge.js +83 -0
- package/dist/workspace/ci-green-workflow.js +199 -0
- package/dist/workspace/ci-green.js +325 -0
- package/dist/workspace/ci-last-green.schema.json +158 -0
- package/dist/workspace/compose-graph.js +235 -0
- package/dist/workspace/compose-reports.js +146 -0
- package/dist/workspace/composites.js +264 -0
- package/dist/workspace/composites.schema.json +617 -0
- package/dist/workspace/conformance/__fixture__/app/package.json +7 -0
- package/dist/workspace/conformance/__fixture__/app/src/server.mjs +29 -0
- package/dist/workspace/conformance/__fixture__/decisions/decision.kind.mjs +54 -0
- package/dist/workspace/conformance/__fixture__/decisions/decision.schema.json +512 -0
- package/dist/workspace/conformance/__fixture__/decisions/fix-001-how-the-app-is-deployed.md +40 -0
- package/dist/workspace/conformance/__fixture__/delivery/chant.config.ts +7 -0
- package/dist/workspace/conformance/__fixture__/delivery/lexicon/index.ts +26 -0
- package/dist/workspace/conformance/__fixture__/delivery/package.json +7 -0
- package/dist/workspace/conformance/__fixture__/delivery/src/app.component.ts +14 -0
- package/dist/workspace/conformance/__fixture__/delivery/src/app.ts +4 -0
- package/dist/workspace/conformance/__fixtures__/reference-broker.js +205 -0
- package/dist/workspace/conformance/__writer_fixture__/answers/answer.kind.mjs +32 -0
- package/dist/workspace/conformance/__writer_fixture__/answers/answer.schema.json +135 -0
- package/dist/workspace/conformance/__writer_fixture__/contracts/contract.kind.mjs +37 -0
- package/dist/workspace/conformance/__writer_fixture__/contracts/contract.schema.json +213 -0
- package/dist/workspace/conformance/__writer_fixture__/decisions/points.json +228 -0
- package/dist/workspace/conformance/__writer_fixture__/drivers/driver.kind.mjs +15 -0
- package/dist/workspace/conformance/__writer_fixture__/drivers/driver.schema.json +38 -0
- package/dist/workspace/conformance/__writer_fixture__/sessions/session.kind.mjs +54 -0
- package/dist/workspace/conformance/__writer_fixture__/sessions/session.schema.json +289 -0
- package/dist/workspace/conformance/__writer_fixture__/work/W-001-the-writer-suite-works-this-item.md +25 -0
- package/dist/workspace/conformance/__writer_fixture__/work/work.kind.mjs +60 -0
- package/dist/workspace/conformance/__writer_fixture__/work/work.schema.json +603 -0
- package/dist/workspace/conformance/broker.js +736 -0
- package/dist/workspace/conformance/index.js +673 -0
- package/dist/workspace/conformance/vitest.js +108 -0
- package/dist/workspace/conformance/writer.js +1080 -0
- package/dist/workspace/decide.js +879 -0
- package/dist/workspace/decision-points.schema.json +135 -135
- package/dist/workspace/declaration-write-cli.js +74 -0
- package/dist/workspace/declaration-write.js +238 -0
- package/dist/workspace/declaration.js +938 -0
- package/dist/workspace/declaration.schema.json +1413 -1413
- package/dist/workspace/declared-kinds.js +106 -0
- package/dist/workspace/environments.js +164 -0
- package/dist/workspace/evidence.schema.json +279 -0
- package/dist/workspace/export-cli.js +185 -0
- package/dist/workspace/export.js +499 -0
- package/dist/workspace/factory-rules.js +175 -0
- package/dist/workspace/generated-files.js +92 -0
- package/dist/workspace/glob.js +45 -0
- package/dist/workspace/graph-cache.js +352 -0
- package/dist/workspace/graph-cli.js +348 -0
- package/dist/workspace/graph.schema.json +1338 -0
- package/dist/workspace/identity-gate-rule.js +75 -0
- package/dist/workspace/identity.js +126 -0
- package/dist/workspace/import.js +283 -0
- package/dist/workspace/init.js +620 -0
- package/dist/workspace/intent-cli.js +263 -0
- package/dist/workspace/intent-joins.js +201 -0
- package/dist/workspace/intent-record.js +352 -0
- package/dist/workspace/intent-record.schema.json +864 -0
- package/dist/workspace/intent.js +1582 -0
- package/dist/workspace/intent.schema.json +2420 -0
- package/dist/workspace/json-edit.js +221 -0
- package/dist/workspace/jsonc.js +235 -0
- package/dist/workspace/kind-readers.js +103 -0
- package/dist/workspace/kinds.js +587 -0
- package/dist/workspace/lexicon-symbols.js +112 -0
- package/dist/workspace/lineage-adopt-cli.js +102 -0
- package/dist/workspace/lineage-adopt.js +360 -0
- package/dist/workspace/lineage-check.js +282 -0
- package/dist/workspace/lineage-cli.js +121 -0
- package/dist/workspace/lineage-hash-index.js +284 -0
- package/dist/workspace/lineage-init.js +507 -0
- package/dist/workspace/lineage-lock.js +387 -0
- package/dist/workspace/lineage-merge.js +45 -0
- package/dist/workspace/lineage-migrations.d.ts.map +1 -1
- package/dist/workspace/lineage-migrations.js +329 -0
- package/dist/workspace/lineage-provenance.js +36 -0
- package/dist/workspace/lineage-update.js +138 -0
- package/dist/workspace/lineage-upgrade-cli.js +131 -0
- package/dist/workspace/lineage-upgrade.js +889 -0
- package/dist/workspace/lineage-vendor.js +171 -0
- package/dist/workspace/lineage-version.js +128 -0
- package/dist/workspace/lineage-versions.js +275 -0
- package/dist/workspace/links.js +330 -0
- package/dist/workspace/ls-generated.js +95 -0
- package/dist/workspace/ls.js +277 -0
- package/dist/workspace/ls.schema.json +333 -0
- package/dist/workspace/member-commands.js +508 -0
- package/dist/workspace/member-handles.js +216 -0
- package/dist/workspace/member-pipeline.js +258 -0
- package/dist/workspace/member-run.js +117 -0
- package/dist/workspace/member-write.schema.json +193 -0
- package/dist/workspace/nested-graph.js +156 -0
- package/dist/workspace/nesting.js +38 -0
- package/dist/workspace/patch.js +301 -0
- package/dist/workspace/patch.schema.json +321 -0
- package/dist/workspace/pin-cli.js +55 -0
- package/dist/workspace/pin-integrity.js +100 -0
- package/dist/workspace/plan-summary.schema.json +155 -0
- package/dist/workspace/point-answer.schema.json +129 -129
- package/dist/workspace/points-cli.js +291 -0
- package/dist/workspace/points-write.schema.json +660 -0
- package/dist/workspace/points.js +521 -0
- package/dist/workspace/points.schema.json +916 -0
- package/dist/workspace/pr-report.schema.json +108 -0
- package/dist/workspace/principal-classes.js +245 -0
- package/dist/workspace/reason-codes.js +326 -0
- package/dist/workspace/record-assets.js +151 -0
- package/dist/workspace/record-decided.js +105 -0
- package/dist/workspace/record-sessions.js +96 -0
- package/dist/workspace/record-source.js +114 -0
- package/dist/workspace/records-amend.schema.json +284 -0
- package/dist/workspace/records-checkout.js +76 -0
- package/dist/workspace/records-cli.js +707 -0
- package/dist/workspace/records-close.js +116 -0
- package/dist/workspace/records-close.schema.json +278 -0
- package/dist/workspace/records-new.schema.json +202 -0
- package/dist/workspace/records-review.schema.json +367 -0
- package/dist/workspace/records-since.js +317 -0
- package/dist/workspace/records-since.schema.json +218 -0
- package/dist/workspace/records-write.js +1229 -0
- package/dist/workspace/records.js +1345 -0
- package/dist/workspace/records.schema.json +604 -0
- package/dist/workspace/reference-kinds/app/package.json +10 -0
- package/dist/workspace/reference-kinds/app/workspace-kinds.json +45 -0
- package/dist/workspace/returns.js +303 -0
- package/dist/workspace/root-refusal.js +75 -0
- package/dist/workspace/run-statement.schema.json +622 -0
- package/dist/workspace/runs-cli.js +584 -0
- package/dist/workspace/runs-write.schema.json +994 -0
- package/dist/workspace/runs.js +708 -0
- package/dist/workspace/runs.schema.json +1257 -0
- package/dist/workspace/runtimes.js +76 -0
- package/dist/workspace/session-kinds.js +83 -0
- package/dist/workspace/signers.schema.json +206 -0
- package/dist/workspace/source-block.js +125 -0
- package/dist/workspace/squash.js +177 -0
- package/dist/workspace/status-gates.js +162 -0
- package/dist/workspace/status-stewards.js +330 -0
- package/dist/workspace/status.js +514 -0
- package/dist/workspace/status.schema.json +998 -0
- package/dist/workspace/steward-index.js +191 -0
- package/dist/workspace/symbols.js +188 -0
- package/dist/workspace/template-manifest.js +227 -0
- package/dist/workspace/template-pins.js +115 -0
- package/dist/workspace/trailer-joins.js +65 -0
- package/dist/workspace/trailers.js +111 -0
- package/dist/workspace/tree.js +136 -0
- package/dist/workspace/trust/attestor.js +63 -0
- package/dist/workspace/trust/dsse.js +108 -0
- package/dist/workspace/trust/evidence-cli.js +175 -0
- package/dist/workspace/trust/evidence.js +161 -0
- package/dist/workspace/trust/gate-seal.js +226 -0
- package/dist/workspace/trust/policy.js +190 -0
- package/dist/workspace/trust/provenance.js +180 -0
- package/dist/workspace/trust/rotation.js +298 -0
- package/dist/workspace/trust/run-commits.js +101 -0
- package/dist/workspace/trust/run-statement.js +182 -0
- package/dist/workspace/trust/seal.js +272 -0
- package/dist/workspace/trust/signers-cli.js +152 -0
- package/dist/workspace/trust/ssh-commit.js +178 -0
- package/dist/workspace/trust/test-repo.js +118 -0
- package/dist/workspace/trust/trust-files.js +193 -0
- package/dist/workspace/trust/verify-cli.js +63 -0
- package/dist/workspace/trust/verify.js +192 -0
- package/dist/workspace/which-chant.js +141 -0
- package/dist/workspace/wip-cli.js +95 -0
- package/dist/workspace/wip-write.schema.json +504 -0
- package/dist/workspace/wip.js +631 -0
- package/dist/workspace/wip.schema.json +334 -0
- package/dist/workspace/work-cli.js +448 -0
- package/dist/workspace/work-evidence.js +122 -0
- package/dist/workspace/work-evidence.schema.json +222 -0
- package/dist/workspace/work-history.schema.json +421 -0
- package/dist/workspace/work-lease.schema.json +246 -0
- package/dist/workspace/work-size.js +77 -0
- package/dist/workspace/work.js +283 -0
- package/dist/workspace/workspace-kinds.schema.json +259 -259
- package/dist/workspace/workspace-principals.schema.json +53 -53
- package/dist/workspace/write-lock-cli.js +105 -0
- package/dist/workspace/write-lock.js +424 -0
- package/dist/workspace/write-lock.schema.json +172 -0
- package/dist/workspace/write-scope.js +484 -0
- package/dist/yaml.js +459 -0
- package/package.json +2 -2
- package/src/cli/commands/check-lexicon-plugin.ts +2 -0
- package/src/cli/commands/lint.ts +3 -0
- package/src/cli/commands/migrate.ts +2 -0
- package/src/cli/compiled-cli.e2e.test.ts +165 -0
- package/src/cli/main.ts +121 -27
- package/src/cli/mcp/workspace-tools.ts +1 -1
- package/src/codegen/pinned-upgrade.ts +2 -0
- package/src/components/discover.ts +2 -0
- package/src/components/sandbox/driver.ts +3 -1
- package/src/config-import.ts +3 -0
- package/src/discovery/fold-import.ts +23 -14
- package/src/discovery/import.ts +2 -0
- package/src/discovery/sandbox/driver.ts +3 -1
- package/src/lexicon-module.ts +3 -0
- package/src/lint/config.ts +1 -1
- package/src/lint/discover.ts +28 -8
- package/src/lint/policy-import.ts +4 -1
- package/src/lint/rule-loader.ts +2 -0
- package/src/op/discover.ts +3 -0
- package/src/ts-loader.test.ts +23 -0
- package/src/ts-loader.ts +122 -0
- package/src/workspace/chant-migrations/chud-lexicon-exit.ts +1 -1
- package/src/workspace/declaration.ts +1 -1
- package/src/workspace/kinds.ts +1 -1
- package/src/workspace/lineage-migrations.ts +2 -0
- package/src/workspace/points.ts +1 -1
- package/src/workspace/principal-classes.ts +1 -1
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `chant workspace evidence sign|verify` (#2553): runner evidence over the
|
|
3
|
+
* records a kind locates, in a DSSE envelope. See ./evidence.ts.
|
|
4
|
+
*
|
|
5
|
+
* `sign` runs in CI or in a service, with a runner key the policy at base
|
|
6
|
+
* lists. It refuses a key the signers file lists: evidence is a machine's
|
|
7
|
+
* statement, and a developer's key cannot make one. `verify` needs no
|
|
8
|
+
* network and no key, only the envelope and the repository.
|
|
9
|
+
*
|
|
10
|
+
* With `--json`, `verify` prints the `evidence.schema.json` document, and a
|
|
11
|
+
* refused `sign` prints its failure branch.
|
|
12
|
+
*/
|
|
13
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
14
|
+
import { formatError, formatSuccess } from "../../cli/format.js";
|
|
15
|
+
import { readerVersion } from "../declaration.js";
|
|
16
|
+
import { gitRevisionSource, gitRoot } from "../record-source.js";
|
|
17
|
+
import { loadRecordKind, readRecords, RecordReadError } from "../records.js";
|
|
18
|
+
import { loadRunnerKey } from "./dsse.js";
|
|
19
|
+
import { buildStatement, signEvidence, verifyEvidence, EVIDENCE_ERROR_CODES } from "./evidence.js";
|
|
20
|
+
import { policyAtBase, resolveBase } from "./provenance.js";
|
|
21
|
+
export const EVIDENCE_CONTRACT_VERSION = 1;
|
|
22
|
+
export const EVIDENCE_OUTPUT_SCHEMA_ID = "https://intentius.io/chant/schemas/workspace/evidence/v1/evidence.schema.json";
|
|
23
|
+
const USAGE = "chant workspace evidence sign --kind <kind file> --key <runner key.pem> --check-id <id> [--claim <file>] [--environment <file>] [--at <rev>] [--base <rev>] [--output <file>] [--json]\n" +
|
|
24
|
+
" chant workspace evidence verify --envelope <file> [--at <rev>] [--base <rev>] [--json]";
|
|
25
|
+
function head() {
|
|
26
|
+
return { $schema: EVIDENCE_OUTPUT_SCHEMA_ID, contract: EVIDENCE_CONTRACT_VERSION, chant: readerVersion() };
|
|
27
|
+
}
|
|
28
|
+
function report(json, at, error, usage = false) {
|
|
29
|
+
if (json)
|
|
30
|
+
console.log(JSON.stringify({ ...head(), at, error }, null, 2));
|
|
31
|
+
else
|
|
32
|
+
console.error(formatError({ message: `${error.message} (${error.code})`, ...(usage ? { hint: USAGE } : {}) }));
|
|
33
|
+
return 1;
|
|
34
|
+
}
|
|
35
|
+
function usage(message) {
|
|
36
|
+
console.error(formatError({ message, hint: USAGE }));
|
|
37
|
+
return 1;
|
|
38
|
+
}
|
|
39
|
+
function commitOf(repo, rev) {
|
|
40
|
+
return resolveBase(repo, rev).commit ?? undefined;
|
|
41
|
+
}
|
|
42
|
+
export async function runWorkspaceEvidence(ctx) {
|
|
43
|
+
const { args } = ctx;
|
|
44
|
+
const sub = args.extraPositional;
|
|
45
|
+
if (sub !== "sign" && sub !== "verify")
|
|
46
|
+
return usage(sub ? `Unknown evidence subcommand: ${sub}` : "chant workspace evidence needs sign or verify");
|
|
47
|
+
const repo = gitRoot(process.cwd());
|
|
48
|
+
if (!repo)
|
|
49
|
+
return report(args.json, null, { code: "not-a-git-repository", message: "runner evidence is bound to git commits, and this directory is not in a git repository" });
|
|
50
|
+
return sub === "sign" ? sign(ctx, repo) : verify(ctx, repo);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Build and sign evidence, or say why not. Refuses a key the signers file
|
|
54
|
+
* lists, and a key the policy at base does not list as a runner.
|
|
55
|
+
*/
|
|
56
|
+
export async function signRecordsEvidence(req) {
|
|
57
|
+
const { repo } = req;
|
|
58
|
+
const at = commitOf(repo, req.at ?? "HEAD");
|
|
59
|
+
if (!at)
|
|
60
|
+
return { error: { code: "revision-unknown", message: `--at ${req.at ?? "HEAD"} names no commit` } };
|
|
61
|
+
const policy = policyAtBase(repo, resolveBase(repo, req.base));
|
|
62
|
+
if (policy.problems.length > 0)
|
|
63
|
+
return { error: { code: "trust-policy-unreadable", message: `the policy at base cannot be read: ${policy.problems.join("; ")}` } };
|
|
64
|
+
let runner;
|
|
65
|
+
try {
|
|
66
|
+
runner = loadRunnerKey(req.keyPem);
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
return { error: { code: "runner-key-invalid", message: `the key is not an Ed25519 private key in PEM: ${err instanceof Error ? err.message : String(err)}` } };
|
|
70
|
+
}
|
|
71
|
+
if (policy.signers.some((s) => s.key === runner.publicKey)) {
|
|
72
|
+
return {
|
|
73
|
+
error: {
|
|
74
|
+
code: "runner-key-is-signer",
|
|
75
|
+
message: `this is a signer's key in ${policy.signersPath}. Runner evidence is signed by a service or CI identity, never by a person's key`,
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
const listed = policy.runners.find((r) => r.key === runner.publicKey);
|
|
80
|
+
if (!listed) {
|
|
81
|
+
return { error: { code: "runner-key-unlisted", message: `the policy at base lists no runner with this key. Add it to .chant/trust.json "runners" first:\n ${runner.publicKey}` } };
|
|
82
|
+
}
|
|
83
|
+
let paths;
|
|
84
|
+
try {
|
|
85
|
+
const loaded = await loadRecordKind(req.kind, req.cwd);
|
|
86
|
+
const read = await readRecords(loaded, { root: repo, source: gitRevisionSource(repo, at) });
|
|
87
|
+
paths = read.records.map((r) => r.path);
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
if (err instanceof RecordReadError && EVIDENCE_ERROR_CODES.includes(err.code)) {
|
|
91
|
+
return { error: { code: err.code, message: err.message } };
|
|
92
|
+
}
|
|
93
|
+
throw err;
|
|
94
|
+
}
|
|
95
|
+
const statement = buildStatement({
|
|
96
|
+
repo,
|
|
97
|
+
commit: at,
|
|
98
|
+
paths,
|
|
99
|
+
runner: listed.principal,
|
|
100
|
+
check: req.checkId,
|
|
101
|
+
...(req.claim ? { claim: req.claim } : {}),
|
|
102
|
+
...(req.environment ? { environment: req.environment } : {}),
|
|
103
|
+
});
|
|
104
|
+
return { envelope: signEvidence(statement, runner.key, runner.publicKey), statement, runner: listed.principal };
|
|
105
|
+
}
|
|
106
|
+
async function sign(ctx, repo) {
|
|
107
|
+
const { args } = ctx;
|
|
108
|
+
if (!args.kind || !args.key || !args.checkId)
|
|
109
|
+
return usage("--kind, --key and --check-id are required");
|
|
110
|
+
const r = await signRecordsEvidence({
|
|
111
|
+
repo,
|
|
112
|
+
kind: args.kind,
|
|
113
|
+
cwd: process.cwd(),
|
|
114
|
+
keyPem: readFileSync(args.key, "utf-8"),
|
|
115
|
+
checkId: args.checkId,
|
|
116
|
+
at: args.at,
|
|
117
|
+
base: args.base,
|
|
118
|
+
...(args.claim ? { claim: readFileSync(args.claim) } : {}),
|
|
119
|
+
...(args.environment ? { environment: readFileSync(args.environment) } : {}),
|
|
120
|
+
});
|
|
121
|
+
if ("error" in r)
|
|
122
|
+
return report(args.json, null, r.error);
|
|
123
|
+
const envelope = JSON.stringify(r.envelope, null, 2) + "\n";
|
|
124
|
+
if (args.output) {
|
|
125
|
+
writeFileSync(args.output, envelope);
|
|
126
|
+
console.error(formatSuccess(`signed evidence for ${r.statement.subject.length} records at ${r.statement.predicate.commit.slice(0, 8)} as ${r.runner}: ${args.output}`));
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
process.stdout.write(envelope);
|
|
130
|
+
}
|
|
131
|
+
return 0;
|
|
132
|
+
}
|
|
133
|
+
/** Verify an envelope file at `at` against the runner keys at base, as the document `--json` prints. */
|
|
134
|
+
export function verifyEvidenceFile(repo, envelopePath, opts = {}) {
|
|
135
|
+
const at = commitOf(repo, opts.at ?? "HEAD");
|
|
136
|
+
if (!at)
|
|
137
|
+
return { ...head(), at: null, error: { code: "revision-unknown", message: `--at ${opts.at ?? "HEAD"} names no commit` } };
|
|
138
|
+
const policy = policyAtBase(repo, resolveBase(repo, opts.base));
|
|
139
|
+
if (policy.problems.length > 0) {
|
|
140
|
+
return { ...head(), at, error: { code: "trust-policy-unreadable", message: `the policy at base cannot be read: ${policy.problems.join("; ")}` } };
|
|
141
|
+
}
|
|
142
|
+
let envelope;
|
|
143
|
+
try {
|
|
144
|
+
envelope = JSON.parse(readFileSync(envelopePath, "utf-8"));
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
return { ...head(), at, error: { code: "envelope-unreadable", message: `--envelope ${envelopePath} could not be read as JSON: ${err instanceof Error ? err.message : String(err)}` } };
|
|
148
|
+
}
|
|
149
|
+
const verdict = verifyEvidence(envelope, policy.runners, repo, at);
|
|
150
|
+
if (!verdict.ok)
|
|
151
|
+
return { ...head(), at, error: { code: verdict.code, message: verdict.reason } };
|
|
152
|
+
return { ...head(), at, ...verdict };
|
|
153
|
+
}
|
|
154
|
+
async function verify(ctx, repo) {
|
|
155
|
+
const { args } = ctx;
|
|
156
|
+
if (!args.envelope)
|
|
157
|
+
return usage("--envelope <file> is required");
|
|
158
|
+
const doc = verifyEvidenceFile(repo, args.envelope, { at: args.at, base: args.base });
|
|
159
|
+
if ("error" in doc)
|
|
160
|
+
return report(args.json, doc.at, doc.error);
|
|
161
|
+
if (args.json) {
|
|
162
|
+
console.log(JSON.stringify(doc, null, 2));
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
for (const s of doc.subjects)
|
|
166
|
+
console.log(` ${s.matches ? "same " : "changed"} ${s.name}`);
|
|
167
|
+
const p = doc.statement.predicate;
|
|
168
|
+
const line = `evidence from ${doc.runner} (${doc.class}) for check ${p.check} at ${p.commit.slice(0, 8)}: ${doc.status} at ${doc.at.slice(0, 8)}`;
|
|
169
|
+
if (doc.status === "current")
|
|
170
|
+
console.log(formatSuccess(line));
|
|
171
|
+
else
|
|
172
|
+
console.error(formatError({ message: line, hint: "evidence is not reused for records that changed; run the check again" }));
|
|
173
|
+
}
|
|
174
|
+
return doc.status === "current" ? 0 : 1;
|
|
175
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runner evidence (#2553, #2524 D5 "Evidence").
|
|
3
|
+
*
|
|
4
|
+
* A runner, meaning a CI job or a service, states that a check ran over a
|
|
5
|
+
* set of records at one commit. The statement is an in-toto Statement v1:
|
|
6
|
+
* each record is a subject, named by its path and hashed, and the predicate
|
|
7
|
+
* binds the commit, its tree, the check, and the digests of the claim and of
|
|
8
|
+
* the environment when given. The runner signs it in a DSSE envelope with its
|
|
9
|
+
* own Ed25519 key.
|
|
10
|
+
*
|
|
11
|
+
* Verifying needs only the envelope, the repository's objects and the runner
|
|
12
|
+
* keys the policy at base lists, so it works offline. Evidence is never
|
|
13
|
+
* reused on trust: a verdict reports, subject by subject, whether the records
|
|
14
|
+
* still hash the same, and evidence for records that changed is `stale`.
|
|
15
|
+
*/
|
|
16
|
+
import { createHash } from "node:crypto";
|
|
17
|
+
import { execFileSync } from "node:child_process";
|
|
18
|
+
import { z } from "zod";
|
|
19
|
+
import { canonicalJson } from "../../effect-receipt.js";
|
|
20
|
+
import { IN_TOTO_PAYLOAD_TYPE, signEnvelope, verifyEnvelope } from "./dsse.js";
|
|
21
|
+
export const STATEMENT_TYPE = "https://in-toto.io/Statement/v1";
|
|
22
|
+
export const RUNNER_EVIDENCE_PREDICATE = "https://intentius.io/chant/runner-evidence/v1";
|
|
23
|
+
/**
|
|
24
|
+
* Why evidence is refused, by `evidence sign` or `evidence verify` (#2553).
|
|
25
|
+
* Each is in `reason-codes.ts` and in `evidence.schema.json`. A sign or verify
|
|
26
|
+
* that can't read the record kind fails with the records read's own code.
|
|
27
|
+
*/
|
|
28
|
+
export const EVIDENCE_ERROR_CODES = [
|
|
29
|
+
"not-a-git-repository",
|
|
30
|
+
"revision-unknown",
|
|
31
|
+
"trust-policy-unreadable",
|
|
32
|
+
"envelope-unreadable",
|
|
33
|
+
"envelope-invalid",
|
|
34
|
+
"envelope-untrusted",
|
|
35
|
+
"evidence-payload-type",
|
|
36
|
+
"evidence-statement-invalid",
|
|
37
|
+
"evidence-runner-mismatch",
|
|
38
|
+
"runner-key-invalid",
|
|
39
|
+
"runner-key-is-signer",
|
|
40
|
+
"runner-key-unlisted",
|
|
41
|
+
"kind-unreadable",
|
|
42
|
+
"kind-invalid",
|
|
43
|
+
"schema-unreadable",
|
|
44
|
+
"schema-id-mismatch",
|
|
45
|
+
"schema-invalid",
|
|
46
|
+
"location-missing",
|
|
47
|
+
];
|
|
48
|
+
const sha256Hex = z.string().regex(/^[0-9a-f]{64}$/);
|
|
49
|
+
const fullCommit = z.string().regex(/^(?:[0-9a-f]{40}|[0-9a-f]{64})$/);
|
|
50
|
+
/** The statement a runner signs. Strict, so a verifier never acts on a field it does not know. */
|
|
51
|
+
export const evidenceStatementSchema = z
|
|
52
|
+
.object({
|
|
53
|
+
_type: z.literal(STATEMENT_TYPE),
|
|
54
|
+
subject: z
|
|
55
|
+
.array(z
|
|
56
|
+
.object({
|
|
57
|
+
name: z
|
|
58
|
+
.string()
|
|
59
|
+
.min(1)
|
|
60
|
+
.refine((n) => !n.startsWith("/") && !n.split("/").includes(".."), "a path inside the repository"),
|
|
61
|
+
digest: z.object({ sha256: sha256Hex }).strict(),
|
|
62
|
+
})
|
|
63
|
+
.strict()),
|
|
64
|
+
predicateType: z.literal(RUNNER_EVIDENCE_PREDICATE),
|
|
65
|
+
predicate: z
|
|
66
|
+
.object({
|
|
67
|
+
runner: z.string().min(1),
|
|
68
|
+
commit: fullCommit,
|
|
69
|
+
tree: fullCommit,
|
|
70
|
+
check: z.string().min(1),
|
|
71
|
+
claim: z.object({ sha256: sha256Hex }).strict().optional(),
|
|
72
|
+
environment: z.object({ sha256: sha256Hex }).strict().optional(),
|
|
73
|
+
})
|
|
74
|
+
.strict(),
|
|
75
|
+
})
|
|
76
|
+
.strict();
|
|
77
|
+
/** SHA-256 of a record's text, line endings normalised as seals do (#2524 D4). */
|
|
78
|
+
export function recordHash(text) {
|
|
79
|
+
return createHash("sha256").update(text.replace(/\r\n?/g, "\n"), "utf8").digest("hex");
|
|
80
|
+
}
|
|
81
|
+
function sha256(bytes) {
|
|
82
|
+
return createHash("sha256").update(bytes).digest("hex");
|
|
83
|
+
}
|
|
84
|
+
function git(repo, args) {
|
|
85
|
+
return execFileSync("git", args, { cwd: repo, encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"], maxBuffer: 256 * 1024 * 1024 });
|
|
86
|
+
}
|
|
87
|
+
function blobAt(repo, commit, path) {
|
|
88
|
+
try {
|
|
89
|
+
return git(repo, ["cat-file", "blob", `${commit}:${path}`]);
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
export function buildStatement(input) {
|
|
96
|
+
const subject = [...input.paths].sort().map((name) => {
|
|
97
|
+
const text = blobAt(input.repo, input.commit, name);
|
|
98
|
+
if (text === undefined)
|
|
99
|
+
throw new Error(`${name} is not in commit ${input.commit.slice(0, 8)}`);
|
|
100
|
+
return { name, digest: { sha256: recordHash(text) } };
|
|
101
|
+
});
|
|
102
|
+
return {
|
|
103
|
+
_type: STATEMENT_TYPE,
|
|
104
|
+
subject,
|
|
105
|
+
predicateType: RUNNER_EVIDENCE_PREDICATE,
|
|
106
|
+
predicate: {
|
|
107
|
+
runner: input.runner,
|
|
108
|
+
commit: input.commit,
|
|
109
|
+
tree: git(input.repo, ["rev-parse", `${input.commit}^{tree}`]).trim(),
|
|
110
|
+
check: input.check,
|
|
111
|
+
...(input.claim ? { claim: { sha256: sha256(input.claim) } } : {}),
|
|
112
|
+
...(input.environment ? { environment: { sha256: sha256(input.environment) } } : {}),
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
export function signEvidence(statement, key, publicKey) {
|
|
117
|
+
return signEnvelope(IN_TOTO_PAYLOAD_TYPE, Buffer.from(canonicalJson(statement), "utf8"), key, publicKey);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Verify an envelope against the runner keys at base, then compare each
|
|
121
|
+
* subject with the record as committed at `at`.
|
|
122
|
+
*/
|
|
123
|
+
export function verifyEvidence(envelope, runners, repo, at) {
|
|
124
|
+
const v = verifyEnvelope(envelope, runners);
|
|
125
|
+
if (!v.ok)
|
|
126
|
+
return v;
|
|
127
|
+
if (v.payloadType !== IN_TOTO_PAYLOAD_TYPE)
|
|
128
|
+
return { ok: false, code: "evidence-payload-type", reason: `payload type ${v.payloadType} is not ${IN_TOTO_PAYLOAD_TYPE}` };
|
|
129
|
+
let raw;
|
|
130
|
+
try {
|
|
131
|
+
raw = JSON.parse(v.payload.toString("utf8"));
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
return { ok: false, code: "evidence-statement-invalid", reason: "the payload is not JSON" };
|
|
135
|
+
}
|
|
136
|
+
const parsed = evidenceStatementSchema.safeParse(raw);
|
|
137
|
+
if (!parsed.success) {
|
|
138
|
+
const detail = parsed.error.issues.map((i) => `${i.path.join(".") || "/"}: ${i.message}`).join("; ");
|
|
139
|
+
return { ok: false, code: "evidence-statement-invalid", reason: `the payload is not a ${RUNNER_EVIDENCE_PREDICATE} statement: ${detail}` };
|
|
140
|
+
}
|
|
141
|
+
const statement = parsed.data;
|
|
142
|
+
// The runner named inside must be the one whose key signed: a runner cannot speak for another.
|
|
143
|
+
if (statement.predicate.runner !== v.principal) {
|
|
144
|
+
return { ok: false, code: "evidence-runner-mismatch", reason: `the statement names runner ${JSON.stringify(statement.predicate.runner)}, but ${v.principal}'s key signed it` };
|
|
145
|
+
}
|
|
146
|
+
const subjects = statement.subject.map((s) => {
|
|
147
|
+
const text = blobAt(repo, at, s.name);
|
|
148
|
+
const now = text === undefined ? null : recordHash(text);
|
|
149
|
+
return { name: s.name, signed: s.digest.sha256, now, matches: now !== null && now === s.digest.sha256 };
|
|
150
|
+
});
|
|
151
|
+
const runner = runners.find((r) => r.principal === v.principal);
|
|
152
|
+
return {
|
|
153
|
+
ok: true,
|
|
154
|
+
status: subjects.every((s) => s.matches) ? "current" : "stale",
|
|
155
|
+
runner: v.principal,
|
|
156
|
+
class: runner.class,
|
|
157
|
+
keyid: v.keyid,
|
|
158
|
+
statement,
|
|
159
|
+
subjects,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A gate approval's seal (#3163, ws-080), checked with node:crypto (#3763).
|
|
3
|
+
*
|
|
4
|
+
* `chant approve --sign` seals an approval with `ssh-keygen -Y sign` in the
|
|
5
|
+
* `chant-gate` namespace, over {@link gateSealPayload}. Signing shells to
|
|
6
|
+
* ssh-keygen; checking does not. This module checks a seal with node:crypto
|
|
7
|
+
* and no zod, and `checkGateSeal` (`./seal.ts`) and `sealedApprovalRule` use
|
|
8
|
+
* it, so an apply job needs no ssh-keygen. A tool that decides a gate from one bundled file
|
|
9
|
+
* (terragucci's apply job) runs the same rule: `@intentius/chant/gate-decision`
|
|
10
|
+
* exports it.
|
|
11
|
+
*
|
|
12
|
+
* An SSHSIG (OpenSSH's PROTOCOL.sshsig) holds the public key, the namespace,
|
|
13
|
+
* the hash algorithm and the signature over `"SSHSIG"`, the namespace, the
|
|
14
|
+
* reserved field, the algorithm and the message's hash. Ed25519, ECDSA (P-256,
|
|
15
|
+
* P-384, P-521), RSA with SHA-2, and the security-key forms of Ed25519 and
|
|
16
|
+
* P-256 verify, with the touch flag required, as ssh-keygen requires it for a
|
|
17
|
+
* signers line with no `no-touch-required` option (which the signers parser
|
|
18
|
+
* does not accept). An RSA signature over SHA-1 does not verify.
|
|
19
|
+
*/
|
|
20
|
+
import { createHash, createPublicKey, verify } from "node:crypto";
|
|
21
|
+
/**
|
|
22
|
+
* The ssh signature namespace of a gate approval's seal (#3163, ws-080), so a
|
|
23
|
+
* verdict, record or commit signature can't stand in for one.
|
|
24
|
+
*/
|
|
25
|
+
export const GATE_SEAL_NAMESPACE = "chant-gate";
|
|
26
|
+
/**
|
|
27
|
+
* The bytes a gate approval's seal signs (#3163): the op (or component), the
|
|
28
|
+
* gate, the environment, the plan digest, the approver and the time, joined
|
|
29
|
+
* by LF with no final newline. An approval that binds no environment or plan
|
|
30
|
+
* signs an empty line for it. A relayed approval (#3402) signs a seventh line,
|
|
31
|
+
* `relayed-by <principal>`, so the relay can't be added, changed or removed
|
|
32
|
+
* after sealing; an approval nobody relayed signs the six lines it always did,
|
|
33
|
+
* so seals made before #3402 still verify.
|
|
34
|
+
*/
|
|
35
|
+
export function gateSealPayload(a) {
|
|
36
|
+
const relay = a.relayedBy !== undefined ? `\nrelayed-by ${a.relayedBy}` : "";
|
|
37
|
+
return Buffer.from(`${a.op}\n${a.gate}\n${a.environment ?? ""}\n${a.planDigest ?? ""}\n${a.resolvedBy}\n${a.timestamp}${relay}`, "utf-8");
|
|
38
|
+
}
|
|
39
|
+
// ── SSHSIG ───────────────────────────────────────────────────────────────
|
|
40
|
+
/** A reader over ssh wire format: `take(n)` bytes, or `take()` one length-prefixed string. */
|
|
41
|
+
function reader(buf) {
|
|
42
|
+
let at = 0;
|
|
43
|
+
const take = (n) => {
|
|
44
|
+
const len = n ?? take(4).readUInt32BE(0);
|
|
45
|
+
if (at + len > buf.length)
|
|
46
|
+
throw new Error("the signature is truncated");
|
|
47
|
+
return buf.subarray(at, (at += len));
|
|
48
|
+
};
|
|
49
|
+
return take;
|
|
50
|
+
}
|
|
51
|
+
const wire = (b) => {
|
|
52
|
+
const v = Buffer.from(b);
|
|
53
|
+
const n = Buffer.alloc(4);
|
|
54
|
+
n.writeUInt32BE(v.length);
|
|
55
|
+
return Buffer.concat([n, v]);
|
|
56
|
+
};
|
|
57
|
+
const hash = (alg, b) => createHash(alg).update(b).digest();
|
|
58
|
+
const b64url = (b) => b.toString("base64url");
|
|
59
|
+
/** An mpint without its sign byte, left-padded to `size` bytes when given. */
|
|
60
|
+
const unsigned = (b, size) => {
|
|
61
|
+
let v = b;
|
|
62
|
+
while (v.length > 1 && v[0] === 0)
|
|
63
|
+
v = v.subarray(1);
|
|
64
|
+
return size === undefined || v.length >= size ? v : Buffer.concat([Buffer.alloc(size - v.length), v]);
|
|
65
|
+
};
|
|
66
|
+
/** `SHA256:<base64>`, the fingerprint ssh-keygen prints for a public key blob. */
|
|
67
|
+
export function sshKeyFingerprint(blob) {
|
|
68
|
+
return `SHA256:${hash("sha256", blob).toString("base64").replace(/=+$/, "")}`;
|
|
69
|
+
}
|
|
70
|
+
const CURVES = {
|
|
71
|
+
nistp256: { crv: "P-256", size: 32, hash: "sha256" },
|
|
72
|
+
nistp384: { crv: "P-384", size: 48, hash: "sha384" },
|
|
73
|
+
nistp521: { crv: "P-521", size: 66, hash: "sha512" },
|
|
74
|
+
};
|
|
75
|
+
/** The key a public key blob holds, what it signs with, and the security key's application when it is one. */
|
|
76
|
+
function publicKey(blob) {
|
|
77
|
+
const take = reader(blob);
|
|
78
|
+
const type = take().toString();
|
|
79
|
+
if (type === "ssh-ed25519" || type === "sk-ssh-ed25519@openssh.com") {
|
|
80
|
+
const key = createPublicKey({ key: { kty: "OKP", crv: "Ed25519", x: b64url(take()) }, format: "jwk" });
|
|
81
|
+
return { type, key, ...(type.startsWith("sk-") ? { application: take() } : {}) };
|
|
82
|
+
}
|
|
83
|
+
if (type.startsWith("ecdsa-sha2-") || type === "sk-ecdsa-sha2-nistp256@openssh.com") {
|
|
84
|
+
const curve = CURVES[take().toString()];
|
|
85
|
+
if (!curve)
|
|
86
|
+
throw new Error(`unsupported curve in ${type}`);
|
|
87
|
+
const q = take();
|
|
88
|
+
if (q[0] !== 4 || q.length !== 1 + 2 * curve.size)
|
|
89
|
+
throw new Error("the ECDSA key is not an uncompressed point");
|
|
90
|
+
const key = createPublicKey({
|
|
91
|
+
key: { kty: "EC", crv: curve.crv, x: b64url(q.subarray(1, 1 + curve.size)), y: b64url(q.subarray(1 + curve.size)) },
|
|
92
|
+
format: "jwk",
|
|
93
|
+
});
|
|
94
|
+
return { type, key, ecdsa: curve, ...(type.startsWith("sk-") ? { application: take() } : {}) };
|
|
95
|
+
}
|
|
96
|
+
if (type === "ssh-rsa") {
|
|
97
|
+
const e = unsigned(take());
|
|
98
|
+
const n = unsigned(take());
|
|
99
|
+
return { type, key: createPublicKey({ key: { kty: "RSA", e: b64url(e), n: b64url(n) }, format: "jwk" }) };
|
|
100
|
+
}
|
|
101
|
+
throw new Error(`unsupported key type ${type}`);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Whether `armored`, an SSHSIG as `ssh-keygen -Y sign` writes it, signs
|
|
105
|
+
* `message` in `namespace` with one of `keys` (public key blobs, ssh wire
|
|
106
|
+
* format). Never throws. On success, `key` is the signing key's fingerprint.
|
|
107
|
+
*/
|
|
108
|
+
export function verifySshSignatureWith(armored, message, namespace, keys) {
|
|
109
|
+
try {
|
|
110
|
+
const body = /-----BEGIN SSH SIGNATURE-----([^-]*)-----END SSH SIGNATURE-----/.exec(armored)?.[1];
|
|
111
|
+
if (body === undefined)
|
|
112
|
+
return { ok: false, reason: "it is not an armored ssh signature" };
|
|
113
|
+
const take = reader(Buffer.from(body.replace(/\s+/g, ""), "base64"));
|
|
114
|
+
if (take(6).toString() !== "SSHSIG" || take(4).readUInt32BE(0) !== 1)
|
|
115
|
+
return { ok: false, reason: "it is not an SSHSIG, version 1" };
|
|
116
|
+
const pk = take();
|
|
117
|
+
const ns = take();
|
|
118
|
+
const reserved = take();
|
|
119
|
+
const alg = take().toString();
|
|
120
|
+
const sigWire = take();
|
|
121
|
+
if (ns.toString() !== namespace)
|
|
122
|
+
return { ok: false, reason: `it is signed in the ${ns.toString()} namespace, not ${namespace}` };
|
|
123
|
+
if (alg !== "sha256" && alg !== "sha512")
|
|
124
|
+
return { ok: false, reason: `it hashes with ${alg}, and only sha256 and sha512 are accepted` };
|
|
125
|
+
if (!keys.some((k) => k.equals(pk)))
|
|
126
|
+
return { ok: false, reason: "signed by a key the policy at base does not list for the approver" };
|
|
127
|
+
let data = Buffer.concat([Buffer.from("SSHSIG"), wire(ns), wire(reserved), wire(alg), wire(hash(alg, message))]);
|
|
128
|
+
const { type, key, ecdsa, application } = publicKey(pk);
|
|
129
|
+
const sig = reader(sigWire);
|
|
130
|
+
const sigType = sig().toString();
|
|
131
|
+
const raw = sig();
|
|
132
|
+
const fingerprint = sshKeyFingerprint(pk);
|
|
133
|
+
const answer = (ok) => (ok ? { ok: true, key: fingerprint } : { ok: false, reason: "the signature does not match the signed fields" });
|
|
134
|
+
if (type === "ssh-rsa") {
|
|
135
|
+
if (sigType !== "rsa-sha2-256" && sigType !== "rsa-sha2-512")
|
|
136
|
+
return { ok: false, reason: `an RSA signature of type ${sigType} is not accepted` };
|
|
137
|
+
return answer(verify(`sha${sigType.slice(9)}`, data, key, raw));
|
|
138
|
+
}
|
|
139
|
+
if (sigType !== type)
|
|
140
|
+
return { ok: false, reason: `a ${sigType} signature from a ${type} key` };
|
|
141
|
+
if (application !== undefined) {
|
|
142
|
+
// A security key signs its application, its flags and counter, then the data's hash; ssh-keygen requires the touch flag.
|
|
143
|
+
const flags = sig(1);
|
|
144
|
+
if (!(flags[0] & 1))
|
|
145
|
+
return { ok: false, reason: "the security key was not touched (the user-presence flag is unset)" };
|
|
146
|
+
data = Buffer.concat([hash("sha256", application), flags, sig(4), hash("sha256", data)]);
|
|
147
|
+
}
|
|
148
|
+
if (ecdsa) {
|
|
149
|
+
const rs = reader(raw);
|
|
150
|
+
const r = unsigned(rs(), ecdsa.size);
|
|
151
|
+
const s = unsigned(rs(), ecdsa.size);
|
|
152
|
+
return answer(verify(application !== undefined ? "sha256" : ecdsa.hash, data, { key, dsaEncoding: "ieee-p1363" }, Buffer.concat([r, s])));
|
|
153
|
+
}
|
|
154
|
+
return answer(verify(null, data, key, raw));
|
|
155
|
+
}
|
|
156
|
+
catch (err) {
|
|
157
|
+
return { ok: false, reason: err instanceof Error ? err.message : String(err) };
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* The key blob an armored SSHSIG carries, or null when it is not one. For
|
|
162
|
+
* `ssh-keygen -Y check-novalidate`'s question, whether the signature is
|
|
163
|
+
* intact whoever's key it is: verify against this key.
|
|
164
|
+
*/
|
|
165
|
+
export function sshSignatureKey(armored) {
|
|
166
|
+
try {
|
|
167
|
+
const body = /-----BEGIN SSH SIGNATURE-----([^-]*)-----END SSH SIGNATURE-----/.exec(armored)?.[1];
|
|
168
|
+
if (body === undefined)
|
|
169
|
+
return null;
|
|
170
|
+
const take = reader(Buffer.from(body.replace(/\s+/g, ""), "base64"));
|
|
171
|
+
if (take(6).toString() !== "SSHSIG" || take(4).readUInt32BE(0) !== 1)
|
|
172
|
+
return null;
|
|
173
|
+
return Buffer.from(take());
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
const normalise = (name) => name.normalize("NFKC").trim().toLowerCase();
|
|
180
|
+
/** Whether ssh-keygen's `namespaces="..."` pattern list admits `namespace`: a `*`/`?` pattern matches, and a `!` pattern that matches refuses. */
|
|
181
|
+
export function namespaceAllowed(list, namespace) {
|
|
182
|
+
if (list === undefined)
|
|
183
|
+
return true;
|
|
184
|
+
let allowed = false;
|
|
185
|
+
for (const raw of list.split(",")) {
|
|
186
|
+
const negated = raw.startsWith("!");
|
|
187
|
+
const pattern = negated ? raw.slice(1) : raw;
|
|
188
|
+
const re = new RegExp(`^${pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".")}$`);
|
|
189
|
+
if (!re.test(namespace))
|
|
190
|
+
continue;
|
|
191
|
+
if (negated)
|
|
192
|
+
return false;
|
|
193
|
+
allowed = true;
|
|
194
|
+
}
|
|
195
|
+
return allowed;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Why this approval does not count toward a sealed gate, or null when it
|
|
199
|
+
* does: its seal verifies, for the approver it names, against a key `signers`
|
|
200
|
+
* lists for that approver in the `chant-gate` namespace. With no signers file
|
|
201
|
+
* at base, nothing counts. The same rule as `sealedApprovalRule` in
|
|
202
|
+
* `../../op/gate-review.ts`, which checks with ssh-keygen.
|
|
203
|
+
*/
|
|
204
|
+
export function gateSealRefusal(signers, a) {
|
|
205
|
+
const where = `${signers.signersPath} at base`;
|
|
206
|
+
if (!signers.active) {
|
|
207
|
+
const why = signers.problems.length > 0 ? `: ${signers.problems.join("; ")}` : "";
|
|
208
|
+
return `the gate is sealed, and there is no signers file (${signers.signersPath}) at base ${signers.base?.slice(0, 12) ?? ""}`.trim() + why;
|
|
209
|
+
}
|
|
210
|
+
const what = `the approval of gate ${a.gate} by ${a.resolvedBy}`;
|
|
211
|
+
if (a.seal === undefined || a.seal === null)
|
|
212
|
+
return `${what} carries no seal`;
|
|
213
|
+
const seal = a.seal;
|
|
214
|
+
if (typeof seal !== "object" || Array.isArray(seal) || typeof seal.signer !== "string" || typeof seal.signature !== "string") {
|
|
215
|
+
return `the seal on ${what} is malformed: it needs signer and signature`;
|
|
216
|
+
}
|
|
217
|
+
if (normalise(seal.signer) !== normalise(a.resolvedBy))
|
|
218
|
+
return `the seal on ${what} is by ${seal.signer}, and its approver is ${a.resolvedBy || "empty"}`;
|
|
219
|
+
const keys = signers.signers
|
|
220
|
+
.filter((s) => normalise(s.principal) === normalise(a.resolvedBy) && namespaceAllowed(s.namespaces, GATE_SEAL_NAMESPACE))
|
|
221
|
+
.map((s) => Buffer.from(s.key.split(" ")[1] ?? "", "base64"));
|
|
222
|
+
if (keys.length === 0)
|
|
223
|
+
return `${a.resolvedBy} has no key in ${where}, so the seal can't count`;
|
|
224
|
+
const r = verifySshSignatureWith(seal.signature, gateSealPayload(a), GATE_SEAL_NAMESPACE, keys);
|
|
225
|
+
return r.ok ? null : `the seal does not verify for ${a.resolvedBy} against ${where}: ${r.reason}`;
|
|
226
|
+
}
|