@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,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which commits of a change agent runs made, and which of those a signed run
|
|
3
|
+
* statement covers (#3192), for `chant workspace verify`.
|
|
4
|
+
*
|
|
5
|
+
* A commit names its run by the `Chant-Run` trailer (ws-075), or a run's end
|
|
6
|
+
* lists it (ws-076). A run statement verified against the runner keys at
|
|
7
|
+
* base names the commits it covers as its subjects. Every `_agent-runs`
|
|
8
|
+
* directory on `chant/lifecycle` is read, the flat one and each member's,
|
|
9
|
+
* from the local branch or, when there is none, from `origin`'s copy. Nothing
|
|
10
|
+
* is fetched: CI fetches `chant/lifecycle` before it verifies.
|
|
11
|
+
*/
|
|
12
|
+
import { execFileSync } from "node:child_process";
|
|
13
|
+
import { AGENT_RUNS_DIR, LEDGER_BRANCH, foldRun, parseRunFile, readRunFiles } from "../runs.js";
|
|
14
|
+
import { RUN_TRAILER } from "../trailers.js";
|
|
15
|
+
import { attestRun } from "./run-statement.js";
|
|
16
|
+
function git(repo, args) {
|
|
17
|
+
try {
|
|
18
|
+
return execFileSync("git", args, { cwd: repo, encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"], maxBuffer: 256 * 1024 * 1024 });
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/** Every run on the ledger, in every member's `_agent-runs`, and the ref and tip read. */
|
|
25
|
+
export function readLedgerRuns(repo) {
|
|
26
|
+
for (const ref of [`refs/heads/${LEDGER_BRANCH}`, `refs/remotes/origin/${LEDGER_BRANCH}`]) {
|
|
27
|
+
const tip = git(repo, ["rev-parse", "--verify", "--quiet", `${ref}^{commit}`])?.trim();
|
|
28
|
+
if (!tip)
|
|
29
|
+
continue;
|
|
30
|
+
const dirs = new Set();
|
|
31
|
+
for (const path of (git(repo, ["ls-tree", "-r", "--name-only", tip]) ?? "").split("\n")) {
|
|
32
|
+
const at = path.lastIndexOf(`${AGENT_RUNS_DIR}/`);
|
|
33
|
+
if (at >= 0 && (at === 0 || path[at - 1] === "/") && path.endsWith(".jsonl"))
|
|
34
|
+
dirs.add(path.slice(0, at + AGENT_RUNS_DIR.length));
|
|
35
|
+
}
|
|
36
|
+
const runs = [];
|
|
37
|
+
for (const dir of dirs) {
|
|
38
|
+
for (const [id, f] of readRunFiles(repo, dir, ref).files) {
|
|
39
|
+
const view = foldRun(id, f.path, parseRunFile(f.content, id).lines);
|
|
40
|
+
if (view)
|
|
41
|
+
runs.push(view);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return { ref, tip, runs };
|
|
45
|
+
}
|
|
46
|
+
return { ref: null, tip: null, runs: [] };
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Judge `commits` (the change, oldest first) against the run ledger: which
|
|
50
|
+
* ones runs made, and which of those a verified statement covers.
|
|
51
|
+
*/
|
|
52
|
+
export function changeRuns(repo, commits, runners) {
|
|
53
|
+
const { ref, runs } = readLedgerRuns(repo);
|
|
54
|
+
const out = { ledger: ref, runners: runners.map((r) => r.principal), commits: [] };
|
|
55
|
+
if (commits.length === 0)
|
|
56
|
+
return out;
|
|
57
|
+
const inChange = new Set(commits);
|
|
58
|
+
const naming = new Map();
|
|
59
|
+
const name = (sha, id) => (naming.get(sha) ?? naming.set(sha, new Set()).get(sha)).add(id);
|
|
60
|
+
// Trailers on the change's own commits.
|
|
61
|
+
const log = git(repo, ["log", "--no-walk=unsorted", `--format=%x00%H%x1f%(trailers:key=${RUN_TRAILER},valueonly,separator=%x1e)`, ...commits]) ?? "";
|
|
62
|
+
for (const rec of log.split("\0")) {
|
|
63
|
+
if (!rec.trim())
|
|
64
|
+
continue;
|
|
65
|
+
const [sha, values] = rec.split("\x1f");
|
|
66
|
+
for (const v of (values ?? "").split("\x1e").map((x) => x.trim()).filter(Boolean))
|
|
67
|
+
name(sha.trim(), v);
|
|
68
|
+
}
|
|
69
|
+
const covered = new Map();
|
|
70
|
+
for (const run of runs) {
|
|
71
|
+
for (const c of run.commits)
|
|
72
|
+
if (inChange.has(c.sha))
|
|
73
|
+
name(c.sha, run.id);
|
|
74
|
+
const a = attestRun(run, runners);
|
|
75
|
+
if (a.status !== "signed")
|
|
76
|
+
continue;
|
|
77
|
+
for (const sha of a.commits)
|
|
78
|
+
if (inChange.has(sha) && !covered.has(sha))
|
|
79
|
+
covered.set(sha, { run: run.id, signer: a.signer, class: a.class });
|
|
80
|
+
}
|
|
81
|
+
const byId = new Map(runs.map((r) => [r.id, r]));
|
|
82
|
+
for (const commit of commits) {
|
|
83
|
+
const ids = [...(naming.get(commit) ?? [])].sort();
|
|
84
|
+
const cover = covered.get(commit);
|
|
85
|
+
if (ids.length === 0 && !cover)
|
|
86
|
+
continue;
|
|
87
|
+
if (cover) {
|
|
88
|
+
out.commits.push({ commit, runs: ids, attested: true, run: cover.run, signer: cover.signer, class: cover.class, reason: `agent run ${cover.run}'s statement, signed by ${cover.signer} (${cover.class}), names this commit` });
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const why = ids.map((id) => {
|
|
92
|
+
const r = byId.get(id);
|
|
93
|
+
if (!r)
|
|
94
|
+
return `${id} is not in the run ledger${ref ? "" : " (there is no chant/lifecycle branch here; fetch it)"}`;
|
|
95
|
+
const a = attestRun(r, runners);
|
|
96
|
+
return a.status === "signed" ? `${id}'s statement, signed by ${a.signer}, does not name this commit` : `${id}: ${a.reason}`;
|
|
97
|
+
});
|
|
98
|
+
out.commits.push({ commit, runs: ids, attested: false, reason: why.join("; ") });
|
|
99
|
+
}
|
|
100
|
+
return out;
|
|
101
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The agent-run statement (#3192, ws-090): a runner's or steward's signed
|
|
3
|
+
* word that an agent run happened as its record says.
|
|
4
|
+
*
|
|
5
|
+
* The run record (#3033, ws-076) is written by whatever ran the agent, so on
|
|
6
|
+
* its own it is as trustworthy as that writer. A statement is an in-toto
|
|
7
|
+
* Statement v1 in a DSSE envelope (./dsse.ts), signed with an Ed25519 key the
|
|
8
|
+
* trust policy at base lists under `runners` in `.chant/trust.json`, the same
|
|
9
|
+
* keys runner evidence uses (#2553, ws-069). A person's key, one the signers
|
|
10
|
+
* file lists, is never a runner key.
|
|
11
|
+
*
|
|
12
|
+
* - `subject`: each commit the run made, by its id (`digest.gitCommit`), with
|
|
13
|
+
* its `git patch-id --stable` as an annotation when it has a patch.
|
|
14
|
+
* - `predicate`: the signer's principal, the run's id and the SHA-256 of its
|
|
15
|
+
* record (the start and end lines), the work item, the harness, the model
|
|
16
|
+
* and provider, and the principal the run worked for (studio-036 b).
|
|
17
|
+
*
|
|
18
|
+
* The statement is stored as a run-ledger fact: a `statement` line in the
|
|
19
|
+
* run's own file on `chant/lifecycle`, after its end. Verifying needs only
|
|
20
|
+
* the envelope, the run's record and the runner keys at base, so it works
|
|
21
|
+
* offline, and a verifier re-checks every stored statement rather than
|
|
22
|
+
* trusting that it was checked when written.
|
|
23
|
+
*/
|
|
24
|
+
import { createHash } from "node:crypto";
|
|
25
|
+
import { z } from "zod";
|
|
26
|
+
import { canonicalJson } from "../../effect-receipt.js";
|
|
27
|
+
import { IN_TOTO_PAYLOAD_TYPE, signEnvelope, verifyEnvelope } from "./dsse.js";
|
|
28
|
+
import { STATEMENT_TYPE } from "./evidence.js";
|
|
29
|
+
export const AGENT_RUN_PREDICATE = "https://intentius.io/chant/agent-run/v1";
|
|
30
|
+
const sha256Hex = z.string().regex(/^[0-9a-f]{64}$/);
|
|
31
|
+
const fullCommit = z.string().regex(/^(?:[0-9a-f]{40}|[0-9a-f]{64})$/);
|
|
32
|
+
const patchId = z.string().regex(/^(?:[0-9a-f]{40}|[0-9a-f]{64})$/);
|
|
33
|
+
const text = z.string().min(1);
|
|
34
|
+
/** The statement a runner signs for a run. Strict, so a verifier never acts on a field it does not know. */
|
|
35
|
+
export const runStatementSchema = z
|
|
36
|
+
.object({
|
|
37
|
+
_type: z.literal(STATEMENT_TYPE),
|
|
38
|
+
subject: z.array(z
|
|
39
|
+
.object({
|
|
40
|
+
name: fullCommit,
|
|
41
|
+
digest: z.object({ gitCommit: fullCommit }).strict(),
|
|
42
|
+
annotations: z.object({ patchId }).strict().optional(),
|
|
43
|
+
})
|
|
44
|
+
.strict()
|
|
45
|
+
.refine((s) => s.name === s.digest.gitCommit, "a commit subject is named by its own id")),
|
|
46
|
+
predicateType: z.literal(AGENT_RUN_PREDICATE),
|
|
47
|
+
predicate: z
|
|
48
|
+
.object({
|
|
49
|
+
signer: text,
|
|
50
|
+
run: z.object({ id: text, record: z.object({ sha256: sha256Hex }).strict() }).strict(),
|
|
51
|
+
unit: z.object({ id: text, kind: text.nullable() }).strict().nullable(),
|
|
52
|
+
harness: z.object({ name: text, version: text.nullable() }).strict(),
|
|
53
|
+
model: text.nullable(),
|
|
54
|
+
provider: text.nullable(),
|
|
55
|
+
by: text.nullable(),
|
|
56
|
+
})
|
|
57
|
+
.strict(),
|
|
58
|
+
})
|
|
59
|
+
.strict();
|
|
60
|
+
/**
|
|
61
|
+
* The SHA-256 of a run's record: the canonical JSON (keys sorted, no
|
|
62
|
+
* whitespace) of the array `[start line, end line]` as the ledger holds them.
|
|
63
|
+
* Statement lines are not part of it, so storing a statement never changes
|
|
64
|
+
* the hash it signs.
|
|
65
|
+
*/
|
|
66
|
+
export function runRecordDigest(start, end) {
|
|
67
|
+
return createHash("sha256").update(canonicalJson([start, end]), "utf8").digest("hex");
|
|
68
|
+
}
|
|
69
|
+
/** The statement for an ended run, as `signer` would sign it. The run's commits are its subjects, sorted by id. */
|
|
70
|
+
export function buildRunStatement(run, signer) {
|
|
71
|
+
if (!run.record)
|
|
72
|
+
throw new Error(`agent run ${run.id} has not ended, so it has no record to sign`);
|
|
73
|
+
const commits = [...new Map(run.commits.map((c) => [c.sha, c])).values()].sort((a, b) => (a.sha < b.sha ? -1 : a.sha > b.sha ? 1 : 0));
|
|
74
|
+
return {
|
|
75
|
+
_type: STATEMENT_TYPE,
|
|
76
|
+
subject: commits.map((c) => ({ name: c.sha, digest: { gitCommit: c.sha }, ...(c.patchId ? { annotations: { patchId: c.patchId } } : {}) })),
|
|
77
|
+
predicateType: AGENT_RUN_PREDICATE,
|
|
78
|
+
predicate: {
|
|
79
|
+
signer,
|
|
80
|
+
run: { id: run.id, record: { sha256: run.record.sha256 } },
|
|
81
|
+
unit: run.unit ? { id: run.unit.id, kind: run.unit.kind } : null,
|
|
82
|
+
harness: { name: run.harness.name, version: run.harness.version },
|
|
83
|
+
model: run.model,
|
|
84
|
+
provider: run.provider,
|
|
85
|
+
by: run.by,
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/** The payload bytes a signer signs: the statement's canonical JSON. Any serialization verifies; this one is reproducible. */
|
|
90
|
+
export function runStatementPayload(statement) {
|
|
91
|
+
return Buffer.from(canonicalJson(statement), "utf8");
|
|
92
|
+
}
|
|
93
|
+
export function signRunStatement(statement, key, publicKey) {
|
|
94
|
+
return signEnvelope(IN_TOTO_PAYLOAD_TYPE, runStatementPayload(statement), key, publicKey);
|
|
95
|
+
}
|
|
96
|
+
// ── Verifying ────────────────────────────────────────────────────────────────
|
|
97
|
+
/**
|
|
98
|
+
* Why a stored statement does not verify. Each is in `reason-codes.ts`.
|
|
99
|
+
* `envelope-invalid` and `envelope-untrusted` are runner evidence's codes:
|
|
100
|
+
* the envelope is the same, and so is the rule for its keys.
|
|
101
|
+
*/
|
|
102
|
+
export const RUN_STATEMENT_FAILURE_CODES = ["envelope-invalid", "envelope-untrusted", "run-statement-invalid", "run-statement-signer-mismatch", "run-statement-mismatch"];
|
|
103
|
+
const same = (a, b) => canonicalJson(a ?? null) === canonicalJson(b ?? null);
|
|
104
|
+
/**
|
|
105
|
+
* Verify one envelope for `run`: a signature by a runner key at base, a
|
|
106
|
+
* well-formed statement whose signer is that key's principal, for this run,
|
|
107
|
+
* and agreeing with its record. Never throws.
|
|
108
|
+
*/
|
|
109
|
+
export function verifyRunStatement(envelope, runners, run) {
|
|
110
|
+
const v = verifyEnvelope(envelope, runners);
|
|
111
|
+
if (!v.ok)
|
|
112
|
+
return { status: v.code === "envelope-untrusted" ? "untrusted" : "invalid", code: v.code, reason: v.reason };
|
|
113
|
+
const runner = runners.find((r) => r.principal === v.principal);
|
|
114
|
+
const signed = { signer: v.principal, class: runner.class, keyid: v.keyid };
|
|
115
|
+
if (v.payloadType !== IN_TOTO_PAYLOAD_TYPE) {
|
|
116
|
+
return { status: "invalid", code: "run-statement-invalid", reason: `payload type ${v.payloadType} is not ${IN_TOTO_PAYLOAD_TYPE}`, ...signed };
|
|
117
|
+
}
|
|
118
|
+
let raw;
|
|
119
|
+
try {
|
|
120
|
+
raw = JSON.parse(v.payload.toString("utf8"));
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return { status: "invalid", code: "run-statement-invalid", reason: "the payload is not JSON", ...signed };
|
|
124
|
+
}
|
|
125
|
+
const parsed = runStatementSchema.safeParse(raw);
|
|
126
|
+
if (!parsed.success) {
|
|
127
|
+
const detail = parsed.error.issues.map((i) => `${i.path.join(".") || "/"}: ${i.message}`).join("; ");
|
|
128
|
+
return { status: "invalid", code: "run-statement-invalid", reason: `the payload is not a ${AGENT_RUN_PREDICATE} statement: ${detail}`, ...signed };
|
|
129
|
+
}
|
|
130
|
+
const statement = parsed.data;
|
|
131
|
+
const p = statement.predicate;
|
|
132
|
+
// A runner cannot speak for another: the principal inside is the one whose key signed.
|
|
133
|
+
if (p.signer !== v.principal) {
|
|
134
|
+
return { status: "invalid", code: "run-statement-signer-mismatch", reason: `the statement names signer ${JSON.stringify(p.signer)}, but ${v.principal}'s key signed it`, ...signed };
|
|
135
|
+
}
|
|
136
|
+
const differs = [];
|
|
137
|
+
if (p.run.id !== run.id)
|
|
138
|
+
differs.push(`it is for run ${p.run.id}`);
|
|
139
|
+
else if (!run.record)
|
|
140
|
+
differs.push("the run has no end in the ledger");
|
|
141
|
+
else if (p.run.record.sha256 !== run.record.sha256)
|
|
142
|
+
differs.push(`the record hashed ${p.run.record.sha256.slice(0, 12)} when signed and ${run.record.sha256.slice(0, 12)} now`);
|
|
143
|
+
if (!same(p.unit, run.unit))
|
|
144
|
+
differs.push(`unit ${JSON.stringify(p.unit?.id ?? null)}, the record says ${JSON.stringify(run.unit?.id ?? null)}`);
|
|
145
|
+
if (!same(p.harness, run.harness))
|
|
146
|
+
differs.push(`harness ${JSON.stringify(p.harness.name)}, the record says ${JSON.stringify(run.harness.name)}`);
|
|
147
|
+
if (p.model !== run.model)
|
|
148
|
+
differs.push(`model ${JSON.stringify(p.model)}, the record says ${JSON.stringify(run.model)}`);
|
|
149
|
+
if (p.provider !== run.provider)
|
|
150
|
+
differs.push(`provider ${JSON.stringify(p.provider)}, the record says ${JSON.stringify(run.provider)}`);
|
|
151
|
+
if (p.by !== run.by)
|
|
152
|
+
differs.push(`by ${JSON.stringify(p.by)}, the record says ${JSON.stringify(run.by)}`);
|
|
153
|
+
if (differs.length > 0) {
|
|
154
|
+
return { status: "mismatch", code: "run-statement-mismatch", reason: `signed by ${v.principal}, but the statement does not match run ${run.id}'s record: ${differs.join("; ")}`, ...signed };
|
|
155
|
+
}
|
|
156
|
+
const n = statement.subject.length;
|
|
157
|
+
return { status: "verified", ...signed, statement, reason: `signed by ${v.principal} (${runner.class}) over the run's record and ${n} commit${n === 1 ? "" : "s"}` };
|
|
158
|
+
}
|
|
159
|
+
const RANK = { mismatch: 0, untrusted: 1, invalid: 2 };
|
|
160
|
+
/** Judge every statement the ledger holds for `run`. */
|
|
161
|
+
export function attestRun(run, runners) {
|
|
162
|
+
const verdicts = run.statements.map((s) => verifyRunStatement(s.envelope, runners, run));
|
|
163
|
+
const good = verdicts.find((v) => v.status === "verified");
|
|
164
|
+
if (good) {
|
|
165
|
+
return { status: "signed", signer: good.signer, class: good.class, keyid: good.keyid, code: null, reason: good.reason, commits: good.statement.subject.map((s) => s.name), statements: verdicts };
|
|
166
|
+
}
|
|
167
|
+
if (verdicts.length === 0) {
|
|
168
|
+
const reason = run.state === "running" ? "the run has not ended, and a statement is signed over an ended run" : "the ledger holds no statement for this run";
|
|
169
|
+
return { status: "unsigned", signer: null, class: null, keyid: null, code: null, reason, commits: [], statements: verdicts };
|
|
170
|
+
}
|
|
171
|
+
const worst = [...verdicts].sort((a, b) => RANK[a.status] - RANK[b.status])[0];
|
|
172
|
+
return {
|
|
173
|
+
status: worst.status,
|
|
174
|
+
signer: worst.signer ?? null,
|
|
175
|
+
class: worst.class ?? null,
|
|
176
|
+
keyid: worst.keyid ?? null,
|
|
177
|
+
code: worst.code,
|
|
178
|
+
reason: worst.reason,
|
|
179
|
+
commits: [],
|
|
180
|
+
statements: verdicts,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sealed verdicts (#2687, part of #2547): a review entry signed by the
|
|
3
|
+
* principal it names, so the quorum counts it only when that principal
|
|
4
|
+
* signed it.
|
|
5
|
+
*
|
|
6
|
+
* A seal is a detached ssh signature, the same mechanism as the ssh-commit
|
|
7
|
+
* attestor (./ssh-commit.ts): `ssh-keygen -Y sign` to make it, and
|
|
8
|
+
* `ssh-keygen -Y verify` against the signers read at base to check it. It is
|
|
9
|
+
* made in its own namespace, `chant-review`, so neither a commit signature
|
|
10
|
+
* nor a signer-set signature can stand in for one.
|
|
11
|
+
*
|
|
12
|
+
* The signed bytes are the record id, the verdict's digest, the verdict, the
|
|
13
|
+
* reviewer and the date, each on its own line with no final newline. The
|
|
14
|
+
* digest is the record's text digest (`recordTextDigest`), so the seal binds
|
|
15
|
+
* the verdict to the text it judged. The seal lives inside the reviews block,
|
|
16
|
+
* which the digest leaves out, so sealing a verdict never moves the digest.
|
|
17
|
+
*
|
|
18
|
+
* A record's author seal (#2688) works the same way, in its own namespace,
|
|
19
|
+
* `chant-record`. It sits in the record's top-level `seal` field, which the
|
|
20
|
+
* digest also leaves out, and signs the record id, the digest, the author
|
|
21
|
+
* (the kind's `reviews.decider` field, `decided_by` for decisions) and the
|
|
22
|
+
* state. An amendment moves the digest, so it has to be signed again.
|
|
23
|
+
*/
|
|
24
|
+
import { execFileSync } from "node:child_process";
|
|
25
|
+
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
26
|
+
import { homedir, tmpdir } from "node:os";
|
|
27
|
+
import { join, resolve } from "node:path";
|
|
28
|
+
import { sshKeygen, verifySshSignature } from "./ssh-commit.js";
|
|
29
|
+
import { GATE_SEAL_NAMESPACE, gateSealPayload, namespaceAllowed, sshSignatureKey, verifySshSignatureWith } from "./gate-seal.js";
|
|
30
|
+
export { GATE_SEAL_NAMESPACE, gateSealPayload } from "./gate-seal.js";
|
|
31
|
+
/** The ssh signature namespace of a verdict seal. */
|
|
32
|
+
export const REVIEW_SEAL_NAMESPACE = "chant-review";
|
|
33
|
+
/** The ssh signature namespace of a record's author seal (#2688). */
|
|
34
|
+
export const RECORD_SEAL_NAMESPACE = "chant-record";
|
|
35
|
+
/** The bytes a verdict seal signs. */
|
|
36
|
+
export function reviewSealPayload(record, digest, verdict, reviewer, on) {
|
|
37
|
+
return Buffer.from(`${record}\n${digest}\n${verdict}\n${reviewer}\n${on}`, "utf-8");
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The bytes a record's author seal signs (#2688): the id, the digest, the
|
|
41
|
+
* author and the state, joined by LF with no final newline. A kind without
|
|
42
|
+
* states signs an empty last line.
|
|
43
|
+
*/
|
|
44
|
+
export function recordSealPayload(record, digest, author, state) {
|
|
45
|
+
return Buffer.from(`${record}\n${digest}\n${author}\n${state ?? ""}`, "utf-8");
|
|
46
|
+
}
|
|
47
|
+
const normalise = (name) => name.normalize("NFKC").trim().toLowerCase();
|
|
48
|
+
const FINGERPRINT = /key (SHA256:[A-Za-z0-9+/=]+)/;
|
|
49
|
+
/**
|
|
50
|
+
* Check a verdict's seal. With a signers file active at base, it verifies
|
|
51
|
+
* against the keys listed there for the reviewer. With none, a seal present
|
|
52
|
+
* is checked for integrity only (`ssh-keygen -Y check-novalidate`): nothing
|
|
53
|
+
* says whose key it is.
|
|
54
|
+
*/
|
|
55
|
+
export function checkVerdictSeal(policy, v) {
|
|
56
|
+
const covered = v.record === null || v.digest === null || typeof v.on !== "string";
|
|
57
|
+
return checkSeal(policy, {
|
|
58
|
+
principal: v.reviewer,
|
|
59
|
+
what: `the verdict by ${v.reviewer}`,
|
|
60
|
+
role: "reviewer",
|
|
61
|
+
namespace: REVIEW_SEAL_NAMESPACE,
|
|
62
|
+
seal: v.seal,
|
|
63
|
+
payload: covered
|
|
64
|
+
? `a seal covers the record id, the verdict's digest and on, and the verdict by ${v.reviewer} lacks one`
|
|
65
|
+
: reviewSealPayload(v.record, v.digest, v.verdict, v.reviewer, v.on),
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Check a record's author seal (#2688), as a verdict's is checked, over
|
|
70
|
+
* {@link recordSealPayload} in the `chant-record` namespace. A record that
|
|
71
|
+
* names no author and carries no seal is `seal-missing` with `attested`
|
|
72
|
+
* null even under an active policy: it claims no author to attest.
|
|
73
|
+
*/
|
|
74
|
+
export function checkRecordSeal(policy, r) {
|
|
75
|
+
const what = r.record ?? "the record";
|
|
76
|
+
if (r.author === null && (r.seal === undefined || r.seal === null)) {
|
|
77
|
+
return { attested: null, code: "seal-missing", message: `${what} names no ${r.authorField}, so it claims no author to seal` };
|
|
78
|
+
}
|
|
79
|
+
return checkSeal(policy, {
|
|
80
|
+
principal: r.author ?? "",
|
|
81
|
+
what,
|
|
82
|
+
role: r.authorField,
|
|
83
|
+
namespace: RECORD_SEAL_NAMESPACE,
|
|
84
|
+
seal: r.seal,
|
|
85
|
+
payload: r.record === null || r.author === null
|
|
86
|
+
? `a record's seal covers its id and its ${r.authorField}, and ${what} lacks one`
|
|
87
|
+
: recordSealPayload(r.record, r.digest, r.author, r.state),
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Check a gate approval's seal (#3163), as a verdict's is checked, over
|
|
92
|
+
* {@link gateSealPayload} in the `chant-gate` namespace: it verifies only
|
|
93
|
+
* when the signers file at base lists a key for the approver.
|
|
94
|
+
*/
|
|
95
|
+
export function checkGateSeal(policy, a) {
|
|
96
|
+
return checkSeal(policy, {
|
|
97
|
+
principal: a.resolvedBy,
|
|
98
|
+
what: `the approval of gate ${a.gate} by ${a.resolvedBy}`,
|
|
99
|
+
role: "approver",
|
|
100
|
+
namespace: GATE_SEAL_NAMESPACE,
|
|
101
|
+
seal: a.seal,
|
|
102
|
+
payload: gateSealPayload(a),
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
function checkSeal(policy, s) {
|
|
106
|
+
const where = `${policy.signersPath} at base`;
|
|
107
|
+
if (s.seal === undefined || s.seal === null) {
|
|
108
|
+
return policy.active
|
|
109
|
+
? { attested: false, code: "seal-missing", message: `${s.what} carries no seal` }
|
|
110
|
+
: { attested: null, code: "seal-missing", message: `${s.what} carries no seal; there is no signers file at base, so none is needed` };
|
|
111
|
+
}
|
|
112
|
+
const seal = s.seal;
|
|
113
|
+
if (typeof seal !== "object" || Array.isArray(seal) || typeof seal.signer !== "string" || typeof seal.signature !== "string") {
|
|
114
|
+
return { attested: false, code: "seal-signature-invalid", message: `the seal on ${s.what} is malformed: it needs signer and signature` };
|
|
115
|
+
}
|
|
116
|
+
if (normalise(seal.signer) !== normalise(s.principal)) {
|
|
117
|
+
return {
|
|
118
|
+
attested: false,
|
|
119
|
+
code: "seal-signature-invalid",
|
|
120
|
+
message: s.role === "reviewer" ? `the seal is by ${seal.signer}, and the verdict is ${s.principal}'s` : `the seal on ${s.what} is by ${seal.signer}, and its ${s.role} is ${s.principal || "empty"}`,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
if (typeof s.payload === "string")
|
|
124
|
+
return { attested: false, code: "seal-signature-invalid", message: s.payload };
|
|
125
|
+
if (!policy.active)
|
|
126
|
+
return checkIntegrity(s.principal, s.payload, seal.signature, s.namespace);
|
|
127
|
+
const listed = policy.signers.filter((x) => normalise(x.principal) === normalise(s.principal));
|
|
128
|
+
if (listed.length === 0 && policy.returnedFrom !== undefined) {
|
|
129
|
+
// Returned work (#2552, ws-004): a signer the service never saw is unverifiable until an admin admits them.
|
|
130
|
+
const intact = checkIntegrity(s.principal, s.payload, seal.signature, s.namespace);
|
|
131
|
+
if (intact.attested === false)
|
|
132
|
+
return intact;
|
|
133
|
+
return {
|
|
134
|
+
attested: null,
|
|
135
|
+
code: "seal-unverifiable",
|
|
136
|
+
message: `${s.what} came back in return ${policy.returnedFrom}, sealed by ${s.principal}${intact.key ? ` with ${intact.key}` : ""}, whom neither ${where} nor an admission for that return lists; it counts once an admin admits the signer (chant workspace admit ${policy.returnedFrom})`,
|
|
137
|
+
...(intact.key ? { key: intact.key } : {}),
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
if (listed.length === 0) {
|
|
141
|
+
return { attested: false, code: "seal-signer-unlisted", message: `${s.principal} has no key in ${where}, so the seal can't count` };
|
|
142
|
+
}
|
|
143
|
+
const r = s.namespace === GATE_SEAL_NAMESPACE ? verifyGate(listed, s.payload, seal.signature) : verifySshSignature(listed, s.payload, seal.signature, s.namespace);
|
|
144
|
+
if (r.ok)
|
|
145
|
+
return { attested: true, message: `sealed by ${r.principal}${r.key ? ` with ${r.key}` : ""}, a signer ${where} lists`, ...(r.key ? { key: r.key } : {}) };
|
|
146
|
+
if (r.missing)
|
|
147
|
+
return { attested: null, code: "seal-unverifiable", message: `the seal by ${s.principal} can't be checked here: ${r.reason}` };
|
|
148
|
+
return { attested: false, code: "seal-signature-invalid", message: `the seal does not verify for ${s.principal} against ${where}: ${r.reason}` };
|
|
149
|
+
}
|
|
150
|
+
/** A gate seal checked with node:crypto (#3785) against the keys `listed` for the approver in the gate namespace. */
|
|
151
|
+
function verifyGate(listed, payload, signature) {
|
|
152
|
+
const keys = listed.filter((x) => namespaceAllowed(x.namespaces, GATE_SEAL_NAMESPACE)).map((x) => Buffer.from(x.key.split(" ")[1] ?? "", "base64"));
|
|
153
|
+
const r = verifySshSignatureWith(signature, payload, GATE_SEAL_NAMESPACE, keys);
|
|
154
|
+
return r.ok ? { ok: true, principal: listed[0].principal, key: r.key } : { ok: false, reason: r.reason };
|
|
155
|
+
}
|
|
156
|
+
/** A seal checked with no signers file: is the signature over these bytes intact? */
|
|
157
|
+
function checkIntegrity(principal, payload, signature, namespace) {
|
|
158
|
+
if (namespace === GATE_SEAL_NAMESPACE) {
|
|
159
|
+
// A gate seal is checked with node:crypto (#3785), against the key it carries.
|
|
160
|
+
const pk = sshSignatureKey(signature);
|
|
161
|
+
const r = pk ? verifySshSignatureWith(signature, payload, namespace, [pk]) : { ok: false, reason: "it is not an SSHSIG" };
|
|
162
|
+
if (!r.ok)
|
|
163
|
+
return { attested: false, code: "seal-signature-invalid", message: `the seal by ${principal} does not verify over this approval, even without a signers file` };
|
|
164
|
+
return { attested: null, code: "seal-unverifiable", message: `the signature is intact (${r.key}), and there is no signers file at base to say whose key it is`, key: r.key };
|
|
165
|
+
}
|
|
166
|
+
const dir = mkdtempSync(join(tmpdir(), "chant-seal-"));
|
|
167
|
+
try {
|
|
168
|
+
const sigFile = join(dir, "signature");
|
|
169
|
+
writeFileSync(sigFile, signature);
|
|
170
|
+
const r = sshKeygen(["-Y", "check-novalidate", "-n", namespace, "-s", sigFile], payload);
|
|
171
|
+
if (r.missing)
|
|
172
|
+
return { attested: null, code: "seal-unverifiable", message: `the seal by ${principal} can't be checked here: ssh-keygen is not installed` };
|
|
173
|
+
if (r.status !== 0) {
|
|
174
|
+
return { attested: false, code: "seal-signature-invalid", message: `the seal by ${principal} does not verify over ${namespace === RECORD_SEAL_NAMESPACE ? "this record" : namespace === GATE_SEAL_NAMESPACE ? "this approval" : "this verdict"}, even without a signers file` };
|
|
175
|
+
}
|
|
176
|
+
const key = FINGERPRINT.exec(r.stdout + r.stderr)?.[1];
|
|
177
|
+
return {
|
|
178
|
+
attested: null,
|
|
179
|
+
code: "seal-unverifiable",
|
|
180
|
+
message: `the signature is intact${key ? ` (${key})` : ""}, and there is no signers file at base to say whose key it is`,
|
|
181
|
+
...(key ? { key } : {}),
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
finally {
|
|
185
|
+
rmSync(dir, { recursive: true, force: true });
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/** Why a seal could not be made. */
|
|
189
|
+
export class SealError extends Error {
|
|
190
|
+
constructor(message) {
|
|
191
|
+
super(message);
|
|
192
|
+
this.name = "SealError";
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* The key `--sign` names: the file given, or with none, git's
|
|
197
|
+
* `user.signingkey` when `gpg.format` is `ssh`, as `git commit -S` reads it.
|
|
198
|
+
* A literal public key (`key::ssh-...`, or `ssh-...`) signs through the ssh
|
|
199
|
+
* agent holding its private half. Returns the file to pass to ssh-keygen,
|
|
200
|
+
* and a cleanup for a temporary one.
|
|
201
|
+
*/
|
|
202
|
+
export function resolveSigningKey(sign, cwd) {
|
|
203
|
+
const none = { cleanup: () => { } };
|
|
204
|
+
if (sign !== true)
|
|
205
|
+
return { file: resolve(cwd, expandHome(sign)), ...none };
|
|
206
|
+
const config = (key) => {
|
|
207
|
+
try {
|
|
208
|
+
return execFileSync("git", ["config", "--get", key], { cwd, encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] }).trim() || undefined;
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
return undefined;
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
const format = config("gpg.format");
|
|
215
|
+
const key = config("user.signingkey");
|
|
216
|
+
if (format !== "ssh" || key === undefined) {
|
|
217
|
+
throw new SealError(`--sign with no key file uses git's user.signingkey when gpg.format is ssh, and git has ${format === "ssh" ? "no user.signingkey" : `gpg.format ${format ?? "unset"}`}; pass --sign <key file>`);
|
|
218
|
+
}
|
|
219
|
+
const literal = key.startsWith("key::") ? key.slice(5) : key.startsWith("ssh-") || key.startsWith("ecdsa-") || key.startsWith("sk-") ? key : undefined;
|
|
220
|
+
if (literal === undefined)
|
|
221
|
+
return { file: resolve(cwd, expandHome(key)), ...none };
|
|
222
|
+
const dir = mkdtempSync(join(tmpdir(), "chant-sign-"));
|
|
223
|
+
const file = join(dir, "key.pub");
|
|
224
|
+
writeFileSync(file, `${literal}\n`);
|
|
225
|
+
return { file, cleanup: () => rmSync(dir, { recursive: true, force: true }) };
|
|
226
|
+
}
|
|
227
|
+
function expandHome(path) {
|
|
228
|
+
return path === "~" ? homedir() : path.startsWith("~/") ? join(homedir(), path.slice(2)) : path;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Seal a verdict with the key in `keyFile` (a private key, or a public key
|
|
232
|
+
* whose private half the ssh agent holds). Throws a {@link SealError}.
|
|
233
|
+
*/
|
|
234
|
+
export function sealVerdict(keyFile, v) {
|
|
235
|
+
return sign(keyFile, reviewSealPayload(v.record, v.digest, v.verdict, v.reviewer, v.on), REVIEW_SEAL_NAMESPACE, v.reviewer);
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Seal a record's author (#2688) with the key in `keyFile`, over
|
|
239
|
+
* {@link recordSealPayload}. Throws a {@link SealError}.
|
|
240
|
+
*/
|
|
241
|
+
export function sealRecord(keyFile, r) {
|
|
242
|
+
return sign(keyFile, recordSealPayload(r.record, r.digest, r.author, r.state), RECORD_SEAL_NAMESPACE, r.author);
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Seal a gate approval (#3163) with the key in `keyFile`, over
|
|
246
|
+
* {@link gateSealPayload}. Throws a {@link SealError}.
|
|
247
|
+
*/
|
|
248
|
+
export function sealGateApproval(keyFile, a) {
|
|
249
|
+
return sign(keyFile, gateSealPayload(a), GATE_SEAL_NAMESPACE, a.resolvedBy);
|
|
250
|
+
}
|
|
251
|
+
function sign(keyFile, payload, namespace, signer) {
|
|
252
|
+
const signed = sshKeygen(["-q", "-Y", "sign", "-n", namespace, "-f", keyFile], payload);
|
|
253
|
+
if (signed.missing)
|
|
254
|
+
throw new SealError("--sign needs ssh-keygen, and it is not installed here");
|
|
255
|
+
if (signed.status !== 0 || !signed.stdout.startsWith("-----BEGIN SSH SIGNATURE-----")) {
|
|
256
|
+
throw new SealError(`ssh-keygen could not sign with ${keyFile}: ${signed.stderr.trim() || `exit ${signed.status}`}`);
|
|
257
|
+
}
|
|
258
|
+
// The fingerprint, read back from the signature itself.
|
|
259
|
+
const dir = mkdtempSync(join(tmpdir(), "chant-seal-"));
|
|
260
|
+
try {
|
|
261
|
+
const sigFile = join(dir, "signature");
|
|
262
|
+
writeFileSync(sigFile, signed.stdout);
|
|
263
|
+
const check = sshKeygen(["-Y", "check-novalidate", "-n", namespace, "-s", sigFile], payload);
|
|
264
|
+
const key = FINGERPRINT.exec(check.stdout + check.stderr)?.[1];
|
|
265
|
+
if (check.status !== 0 || !key)
|
|
266
|
+
throw new SealError(`the signature ssh-keygen made with ${keyFile} does not check: ${check.stderr.trim()}`);
|
|
267
|
+
return { signer, key, signature: signed.stdout };
|
|
268
|
+
}
|
|
269
|
+
finally {
|
|
270
|
+
rmSync(dir, { recursive: true, force: true });
|
|
271
|
+
}
|
|
272
|
+
}
|